<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PPT编辑器 - {{ project.title }}</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
    <!-- CodeMirror CSS -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/theme/monokai.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/theme/material.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/theme/dracula.min.css">
    <!-- CodeMirror Search Dialog CSS -->
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/dialog/dialog.min.css">
    <style>
        :root {
            --primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            --secondary-gradient: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
            --accent-gradient: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
            --success-gradient: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
            --warning-gradient: linear-gradient(135deg, #fa709a 0%, #fee140 100%);

            --glass-bg: rgba(255, 255, 255, 0.25);
            --glass-border: rgba(255, 255, 255, 0.18);
            --glass-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);

            --text-primary: #2d3748;
            --text-secondary: #4a5568;
            --text-muted: #718096;

            --border-radius-sm: 12px;
            --border-radius-md: 16px;
            --border-radius-lg: 24px;
            --border-radius-xl: 32px;

            --spacing-xs: 8px;
            --spacing-sm: 12px;
            --spacing-md: 16px;
            --spacing-lg: 24px;
            --spacing-xl: 32px;
            --spacing-2xl: 48px;
        }

        body {
            background: var(--primary-gradient);
            min-height: 100vh;
            font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
            position: relative;
            overflow-x: hidden;
        }

        body::before {
            content: '';
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background:
                radial-gradient(circle at 20% 80%, rgba(120, 119, 198, 0.3) 0%, transparent 50%),
                radial-gradient(circle at 80% 20%, rgba(255, 119, 198, 0.3) 0%, transparent 50%),
                radial-gradient(circle at 40% 40%, rgba(120, 219, 255, 0.2) 0%, transparent 50%);
            pointer-events: none;
            z-index: -1;
        }

        .editor-container {
            background: var(--glass-bg);
            backdrop-filter: blur(30px);
            border: 1px solid var(--glass-border);
            border-radius: var(--border-radius-xl);
            box-shadow: var(--glass-shadow);
            margin: var(--spacing-lg);
            overflow: hidden;
            position: relative;
            z-index: 1;
        }

        .editor-header {
            background: var(--primary-gradient);
            color: white;
            padding: var(--spacing-md) var(--spacing-xl);
            position: relative;
            overflow: hidden;
            z-index: 10;
        }

        .editor-header::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background:
                radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.1) 0%, transparent 50%),
                radial-gradient(circle at 70% 70%, rgba(255, 255, 255, 0.05) 0%, transparent 50%);
            animation: headerFloat 25s ease-in-out infinite;
        }

        @keyframes headerFloat {
            0%, 100% { transform: scale(1) rotate(0deg); }
            50% { transform: scale(1.02) rotate(1deg); }
        }

        .editor-header h1,
        .editor-header h2 {
            position: relative;
            z-index: 1;
            text-shadow: 0 2px 8px rgba(0,0,0,0.3);
            font-weight: 700;
            font-size: 1.5rem;
            letter-spacing: -0.01em;
            margin: 0;
        }

        .editor-header p {
            position: relative;
            z-index: 1;
            opacity: 0.9;
            font-size: 0.9rem;
            font-weight: 500;
            margin: var(--spacing-xs) 0 0 0;
        }
        
        .slides-sidebar {
            background: var(--glass-bg);
            backdrop-filter: blur(15px);
            border-right: 1px solid var(--glass-border);
            height: calc(100vh - 140px);
            overflow-y: auto;
            display: flex;
            flex-direction: column;
            min-width: 280px;
        }

        .slides-container {
            flex: 1;
            display: flex;
            flex-direction: column;
            gap: var(--spacing-sm);
            padding: var(--spacing-md);
        }

        .slide-thumbnail {
            border: 2px solid transparent;
            border-radius: var(--border-radius-md);
            cursor: pointer;
            transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
            background: var(--glass-bg);
            backdrop-filter: blur(10px);
            box-shadow: 0 4px 15px rgba(31, 38, 135, 0.2);
            position: relative;
            user-select: none;
            flex-shrink: 0;
            margin: 0;
            overflow: hidden;
        }

        .slide-thumbnail::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            height: 2px;
            background: var(--accent-gradient);
            transform: scaleX(0);
            transition: transform 0.3s ease;
            z-index: 1;
        }

        .slide-thumbnail:hover {
            border-color: rgba(79, 172, 254, 0.5);
            transform: translateY(-4px) scale(1.02);
            box-shadow: 0 8px 25px rgba(79, 172, 254, 0.3);
        }

        .slide-thumbnail:hover::before {
            transform: scaleX(1);
        }

        .slide-thumbnail.active {
            border-color: rgba(67, 233, 123, 0.7);
            box-shadow: 0 8px 25px rgba(67, 233, 123, 0.4);
            transform: translateY(-4px) scale(1.02);
        }

        .slide-thumbnail.active::before {
            background: var(--success-gradient);
            transform: scaleX(1);
        }

        .slide-thumbnail.dragging {
            opacity: 0.5;
            transform: rotate(5deg) scale(0.95);
            z-index: 1000;
        }

        .slide-thumbnail.drag-over {
            border-color: #ffc107;
            background: rgba(255, 193, 7, 0.1);
        }

        .slide-preview {
            width: 100%;
            height: 135px; /* 调整高度以适应新的缩放比例：720*0.1875=135px */
            border: none;
            border-radius: 6px 6px 0 0;
            pointer-events: none;
            position: relative;
            overflow: hidden;
            background: #f8f9fa;
        }

        .slide-preview iframe {
            position: absolute;
            top: 0;
            left: 0;
            border: none;
            background: white;
            /* 设置iframe为1280x720，然后缩放到容器大小 */
            width: 1280px;
            height: 720px;
            transform-origin: top left;
            /* 计算缩放比例以填满容器：容器宽度约240px，240/1280=0.1875 */
            transform: scale(0.1875);
        }
        
        .slide-title {
            padding: 4px 2px;
            font-size: 10px;
            font-weight: bold;
            text-align: center;
            background: #f8f9fa;
            border-top: 1px solid #dee2e6;
            line-height: 1.1;
            height: 24px; /* 固定标题高度 */
            display: flex;
            align-items: center;
            justify-content: center;
        }
        
        .main-editor {
            height: calc(100vh - 140px);
            display: flex;
            flex-direction: column;
        }
        
        .editor-toolbar {
            background: var(--glass-bg);
            backdrop-filter: blur(15px);
            border-bottom: 1px solid var(--glass-border);
            padding: var(--spacing-sm) var(--spacing-lg);
            display: flex;
            justify-content: space-between;
            align-items: center;
            box-shadow: 0 2px 15px rgba(31, 38, 135, 0.1);
            position: relative;
        }
        
        .editor-content {
            flex: 1;
            display: flex;
        }
        
        .preview-pane {
            flex: 1;
            background: #f8f9fa;
            border-right: 1px solid #dee2e6;
            position: relative;
        }
        
        .edit-pane {
            flex: 1;
            background: white;
            height: 100%;
            overflow: hidden;
            position: relative;
        }
        
        .slide-frame {
            position: absolute;
            top: 50%;
            left: 50%;
            width: 1280px;
            height: 720px;
            border: none;
            background: white;
            border-radius: 8px;
            transform-origin: center center;
            /* 初始变换，JavaScript会动态调整缩放比例 */
            transform: translate(-50%, -50%) scale(1);
        }

        /* 右侧iframe的响应式缩放 */
        .preview-pane {
            flex: 1;
            background: #f8f9fa;
            border-right: 1px solid #dee2e6;
            position: relative;
            overflow: hidden;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .slide-frame-container {
            width: 100%;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            background: #f8f9fa;
            border-radius: 8px;
            padding: 10px;
            box-sizing: border-box;
            overflow: hidden;
        }

        .slide-frame-wrapper {
            position: relative;
            background: white;
            border-radius: 8px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
            /* 固定16:9比例，自适应缩放 */
            width: 100%;
            height: 100%;
            max-width: calc(100vh * 16/9 - 40px); /* 基于高度计算最大宽度 */
            max-height: calc(100vw * 9/16 - 40px); /* 基于宽度计算最大高度 */
        }
        
        .code-editor {
            width: 100%;
            height: 100%;
            border: none;
            font-family: 'Courier New', monospace;
            font-size: 14px;
            padding: 20px;
            resize: none;
            outline: none;
        }

        /* CodeMirror编辑器样式优化 */
        .CodeMirror {
            height: 100% !important;
            font-family: 'Consolas', 'Monaco', 'Courier New', monospace !important;
            font-size: 14px !important;
            line-height: 1.5 !important;
            border: none !important;
            position: absolute !important;
            top: 0 !important;
            left: 0 !important;
            right: 0 !important;
            bottom: 0 !important;
            min-height: 400px !important;
        }

        .CodeMirror-scroll {
            padding: 20px !important;
            overflow-y: auto !important;
            overflow-x: auto !important;
            max-height: none !important;
            min-height: 400px !important;
        }

        .CodeMirror-scrollbar-filler {
            background: transparent !important;
        }

        .CodeMirror-vscrollbar, .CodeMirror-hscrollbar {
            outline: none !important;
        }

        .CodeMirror-vscrollbar {
            right: 0 !important;
            top: 0 !important;
            overflow-x: hidden !important;
            overflow-y: auto !important;
        }

        .CodeMirror-hscrollbar {
            bottom: 0 !important;
            left: 0 !important;
            overflow-y: hidden !important;
            overflow-x: auto !important;
        }

        .CodeMirror-gutters {
            background: #2c3e50 !important;
            border-right: 1px solid #34495e !important;
        }

        .CodeMirror-linenumber {
            color: #7f8c8d !important;
            padding: 0 8px !important;
        }

        .CodeMirror-cursor {
            border-left: 2px solid #e74c3c !important;
        }

        .CodeMirror-selected {
            background: rgba(52, 152, 219, 0.2) !important;
        }

        .CodeMirror-focused .CodeMirror-selected {
            background: rgba(52, 152, 219, 0.3) !important;
        }

        /* 主题色彩调整 */
        .cm-s-material .CodeMirror {
            background: #263238 !important;
            color: #eeffff !important;
        }

        .cm-s-material .CodeMirror-gutters {
            background: #2c3e50 !important;
        }

        .cm-s-material .cm-tag {
            color: #f07178 !important;
        }

        .cm-s-material .cm-attribute {
            color: #c792ea !important;
        }

        .cm-s-material .cm-string {
            color: #c3e88d !important;
        }

        .cm-s-material .cm-comment {
            color: #546e7a !important;
        }

        /* CodeMirror搜索对话框样式优化 */
        .CodeMirror-dialog {
            position: absolute;
            left: 0;
            right: 0;
            background: #2c3e50 !important;
            color: white !important;
            z-index: 15;
            padding: 10px 15px !important;
            border: none !important;
            border-bottom: 2px solid #3498db !important;
            box-shadow: 0 2px 10px rgba(0,0,0,0.3) !important;
        }

        .CodeMirror-dialog input {
            border: 1px solid #34495e !important;
            outline: none !important;
            background: #34495e !important;
            color: white !important;
            padding: 8px 12px !important;
            border-radius: 4px !important;
            font-size: 14px !important;
            margin: 0 5px !important;
            min-width: 200px !important;
        }

        .CodeMirror-dialog input:focus {
            border-color: #3498db !important;
            box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.3) !important;
        }

        .CodeMirror-dialog button {
            background: #3498db !important;
            color: white !important;
            border: none !important;
            padding: 8px 15px !important;
            border-radius: 4px !important;
            cursor: pointer !important;
            font-size: 14px !important;
            margin: 0 3px !important;
            transition: background-color 0.2s ease !important;
        }

        .CodeMirror-dialog button:hover {
            background: #2980b9 !important;
        }

        .CodeMirror-dialog span {
            color: white !important;
            font-size: 14px !important;
            margin: 0 5px !important;
        }

        /* 搜索高亮样式 */
        .CodeMirror-searching {
            background-color: rgba(255, 255, 0, 0.4) !important;
            border: 1px solid rgba(255, 193, 7, 0.8) !important;
            border-radius: 2px !important;
        }

        .cm-searching {
            background-color: rgba(255, 255, 0, 0.4) !important;
            border: 1px solid rgba(255, 193, 7, 0.8) !important;
            border-radius: 2px !important;
        }

        /* 当前搜索结果高亮 */
        .CodeMirror-search-match {
            background-color: rgba(255, 165, 0, 0.6) !important;
            border: 2px solid #ff6b35 !important;
            border-radius: 3px !important;
        }

        /* 搜索对话框关闭按钮样式 */
        .CodeMirror-dialog .CodeMirror-search-close {
            position: absolute !important;
            right: 10px !important;
            top: 50% !important;
            transform: translateY(-50%) !important;
            background: #e74c3c !important;
            color: white !important;
            border: none !important;
            border-radius: 50% !important;
            width: 24px !important;
            height: 24px !important;
            font-size: 12px !important;
            cursor: pointer !important;
            display: flex !important;
            align-items: center !important;
            justify-content: center !important;
        }

        .CodeMirror-dialog .CodeMirror-search-close:hover {
            background: #c0392b !important;
        }
        
        .btn-group-custom {
            display: flex;
            gap: var(--spacing-md);
            align-items: center;
            justify-content: center;
            flex-wrap: wrap;
        }

        .btn-group-custom .btn {
            min-width: 140px;
            white-space: nowrap;
            padding: var(--spacing-sm) var(--spacing-lg);
            border-radius: var(--border-radius-md);
            font-weight: 600;
            transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
            border: none;
            cursor: pointer;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            gap: var(--spacing-xs);
            position: relative;
            overflow: hidden;
        }

        .btn-group-custom .btn::before {
            content: '';
            position: absolute;
            top: 0;
            left: -100%;
            width: 100%;
            height: 100%;
            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
            transition: left 0.6s;
        }

        .btn-group-custom .btn:hover::before {
            left: 100%;
        }

        .btn-primary {
            background: var(--primary-gradient);
            color: white;
            box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
        }

        .btn-success {
            background: var(--success-gradient);
            color: white;
            box-shadow: 0 4px 15px rgba(67, 233, 123, 0.3);
        }

        .btn-info {
            background: var(--accent-gradient);
            color: white;
            box-shadow: 0 4px 15px rgba(79, 172, 254, 0.3);
        }

        .btn-warning {
            background: var(--warning-gradient);
            color: white;
            box-shadow: 0 4px 15px rgba(250, 112, 154, 0.3);
        }

        .btn-group-custom .btn:hover {
            transform: translateY(-2px) scale(1.02);
        }

        /* 返回按钮样式 */
        .btn-outline-light {
            background: rgba(255, 255, 255, 0.1);
            color: white;
            border: 2px solid rgba(255, 255, 255, 0.3);
            padding: var(--spacing-sm) var(--spacing-lg);
            border-radius: var(--border-radius-md);
            font-weight: 600;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            text-decoration: none;
            display: inline-flex;
            align-items: center;
            gap: var(--spacing-xs);
            position: relative;
            z-index: 20;
            cursor: pointer;
        }

        .btn-outline-light:hover {
            background: rgba(255, 255, 255, 0.2);
            border-color: rgba(255, 255, 255, 0.5);
            color: white;
            transform: translateY(-2px) scale(1.02);
            box-shadow: 0 4px 15px rgba(255, 255, 255, 0.2);
            text-decoration: none;
        }

        .btn-outline-light:active {
            transform: translateY(0) scale(0.98);
        }

        .mode-toggle {
            background: var(--accent-gradient);
            color: white;
            border: none;
            padding: var(--spacing-sm) var(--spacing-lg);
            border-radius: var(--border-radius-lg);
            cursor: pointer;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            font-weight: 600;
            box-shadow: 0 4px 15px rgba(79, 172, 254, 0.3);
        }

        .mode-toggle:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 20px rgba(79, 172, 254, 0.4);
        }

        .mode-toggle.active {
            background: var(--success-gradient);
            box-shadow: 0 6px 20px rgba(67, 233, 123, 0.4);
        }

        .export-section {
            background: var(--glass-bg);
            backdrop-filter: blur(15px);
            border-top: 1px solid var(--glass-border);
            padding: var(--spacing-lg) var(--spacing-xl);
            text-align: center;
            position: sticky;
            bottom: 0;
            z-index: 100;
            box-shadow: 0 -4px 20px rgba(31, 38, 135, 0.2);
            min-height: 80px;
        }

        /* Slideshow styles - 优化流畅度 */
        .slideshow-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: black;
            z-index: 9999;
            display: none;
            justify-content: center;
            align-items: center;
            /* 硬件加速 */
            transform: translateZ(0);
            will-change: opacity;
        }

        .slideshow-container {
            width: 100%;
            height: 100%;
            position: relative;
            display: flex;
            justify-content: center;
            align-items: center;
            /* 硬件加速 */
            transform: translateZ(0);
            padding: 20px;
            box-sizing: border-box;
        }

        .slideshow-slide {
            background: white;
            border-radius: 10px;
            box-shadow: 0 10px 30px rgba(255,255,255,0.2);
            overflow: hidden;
            position: relative;
            /* 使用flex确保PPT居中且尺寸自适应 */
            width: 100%;
            height: 100%;
            max-width: calc(100vh * 16/9 - 40px); /* 基于高度计算最大宽度，保持16:9比例 */
            max-height: calc(100vw * 9/16 - 40px); /* 基于宽度计算最大高度，保持16:9比例 */
            aspect-ratio: 16/9; /* 强制保持16:9比例 */
            /* 硬件加速 */
            transform: translateZ(0);
            will-change: transform;
        }

        .slideshow-slide iframe {
            width: 100%;
            height: 100%;
            border: none;
            background: white;
            /* 移除过渡效果，避免闪烁 */
            transform-origin: center center;
            /* 硬件加速 */
            transform: translateZ(0);
            will-change: opacity;
            /* 确保iframe始终可见 */
            opacity: 1;
        }

        /* 双缓冲iframe系统 */
        .slideshow-slide .iframe-container {
            position: relative;
            width: 100%;
            height: 100%;
        }

        .slideshow-slide .iframe-container iframe {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
        }

        .slideshow-slide .iframe-container iframe.hidden {
            opacity: 0;
            pointer-events: none;
        }

        .slideshow-slide .iframe-container iframe.visible {
            opacity: 1;
            pointer-events: auto;
        }

        /* 移除加载状态覆盖层，避免闪烁 */
        .slideshow-slide::before {
            display: none;
        }

        .slideshow-controls {
            position: absolute;
            bottom: 30px;
            left: 50%;
            transform: translateX(-50%);
            display: flex;
            gap: 20px;
            align-items: center;
        }

        .slideshow-btn {
            background: rgba(255,255,255,0.2);
            color: white;
            border: 2px solid rgba(255,255,255,0.3);
            padding: 10px 20px;
            border-radius: 25px;
            cursor: pointer;
            transition: all 0.3s ease;
            font-size: 16px;
        }

        .slideshow-btn:hover {
            background: rgba(255,255,255,0.3);
            border-color: rgba(255,255,255,0.5);
        }

        .slideshow-info {
            color: white;
            font-size: 18px;
            font-weight: bold;
        }

        .slideshow-exit {
            position: absolute;
            top: 30px;
            right: 30px;
            background: rgba(255,255,255,0.2);
            color: white;
            border: 2px solid rgba(255,255,255,0.3);
            padding: 10px 15px;
            border-radius: 50%;
            cursor: pointer;
            font-size: 20px;
            transition: all 0.3s ease;
        }

        .slideshow-exit:hover {
            background: rgba(255,255,255,0.3);
            border-color: rgba(255,255,255,0.5);
        }

        /* 响应式设计 */
        @media (max-width: 1200px) {
            .slide-preview {
                height: 115px; /* 200px容器宽度，200/1280=0.156，720*0.156=112.32px */
            }
            .slide-preview iframe {
                transform: scale(0.156);
            }

            .slide-frame-wrapper {
                transform: scale(0.8);
            }
        }

        @media (max-width: 992px) {
            .slides-sidebar {
                flex: 0 0 220px !important;
            }

            .slide-preview {
                height: 115px; /* 200px容器宽度，200/1280=0.156，720*0.156=112.32px */
            }
            .slide-preview iframe {
                transform: scale(0.156);
            }

            .slide-title {
                font-size: 9px;
                padding: 3px 2px;
                height: 20px;
            }

            .slide-frame-wrapper {
                transform: scale(0.7);
            }
        }

        @media (max-width: 768px) {
            .slides-sidebar {
                flex: 0 0 200px !important;
            }

            .slide-preview {
                height: 105px; /* 180px容器宽度，180/1280=0.141，720*0.141=101.52px */
            }
            .slide-preview iframe {
                transform: scale(0.141);
            }

            .slide-title {
                font-size: 8px;
                padding: 2px 1px;
                height: 18px;
            }

            .slides-container {
                gap: 3px;
                padding: 3px;
            }

            .slide-frame-wrapper {
                transform: scale(0.6);
            }
        }

        @media (max-width: 576px) {
            .editor-container {
                margin: 10px;
            }

            .slides-sidebar {
                flex: 0 0 180px !important;
            }

            .slide-preview {
                height: 95px; /* 160px容器宽度，160/1280=0.125，720*0.125=90px */
            }
            .slide-preview iframe {
                transform: scale(0.125);
            }

            .slide-title {
                font-size: 7px;
                padding: 2px 1px;
                height: 16px;
            }

            .slide-frame-wrapper {
                transform: scale(0.5);
            }

            /* 小屏幕上的导出按钮优化 */
            .btn-group-custom {
                flex-direction: column;
                gap: 10px;
            }

            .btn-group-custom .btn {
                min-width: 100%;
                font-size: 14px;
            }

            .export-section {
                padding: 10px 15px;
            }
        }

        /* 右键菜单样式 */
        .context-menu {
            position: fixed;
            background: white;
            border: 1px solid #ddd;
            border-radius: 8px;
            box-shadow: 0 4px 20px rgba(0,0,0,0.15);
            z-index: 2000;
            min-width: 180px;
            display: none;
            overflow: hidden;
        }

        .context-menu-item {
            padding: 12px 16px;
            cursor: pointer;
            border-bottom: 1px solid #f0f0f0;
            display: flex;
            align-items: center;
            gap: 10px;
            font-size: 14px;
            color: #333;
            transition: background-color 0.2s ease;
        }

        .context-menu-item:last-child {
            border-bottom: none;
        }

        .context-menu-item:hover {
            background: #f8f9fa;
        }

        .context-menu-item.disabled {
            color: #999;
            cursor: not-allowed;
        }

        .context-menu-item.disabled:hover {
            background: white;
        }

        .context-menu-item i {
            width: 16px;
            text-align: center;
        }

        /* 通知样式 */
        .notification {
            position: fixed;
            top: 20px;
            right: 20px;
            padding: 15px 20px;
            border-radius: 8px;
            color: white;
            font-weight: bold;
            z-index: 10000;
            max-width: 300px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.15);
            animation: slideInRight 0.3s ease;
        }

        .notification-info {
            background: #17a2b8;
        }

        .notification-success {
            background: #28a745;
        }

        .notification-warning {
            background: #ffc107;
            color: #212529;
        }

        .notification-error {
            background: #dc3545;
        }

        @keyframes slideInRight {
            from {
                transform: translateX(100%);
                opacity: 0;
            }
            to {
                transform: translateX(0);
                opacity: 1;
            }
        }

        /* 拖拽指示器 */
        .drag-indicator {
            position: absolute;
            left: 5px;
            right: 5px;
            height: 3px;
            background: #ffc107;
            border-radius: 2px;
            display: none;
            z-index: 100;
        }

        .drag-indicator.top {
            top: -2px;
        }

        .drag-indicator.bottom {
            bottom: -2px;
        }

        .drag-indicator.show {
            display: block;
        }

        /* AI编辑侧栏样式 - 与页面风格统一 */
        .ai-edit-sidebar {
            position: fixed;
            top: 0;
            right: -650px; /* 增加默认宽度 */
            width: 650px; /* 增加默认宽度 */
            height: 100vh;
            background: var(--glass-bg);
            backdrop-filter: blur(30px);
            border: 1px solid var(--glass-border);
            border-right: none;
            border-radius: var(--border-radius-xl) 0 0 var(--border-radius-xl);
            box-shadow: var(--glass-shadow);
            z-index: 2000;
            transition: right 0.4s cubic-bezier(0.4, 0, 0.2, 1);
            display: flex;
            flex-direction: column;
            resize: horizontal; /* 允许水平调整大小 */
            min-width: 500px; /* 最小宽度 */
            max-width: 1000px; /* 最大宽度 */
            overflow: hidden;
        }

        .ai-edit-sidebar.open {
            right: 0;
        }

        .ai-edit-sidebar::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background:
                radial-gradient(circle at 20% 20%, rgba(79, 172, 254, 0.1) 0%, transparent 50%),
                radial-gradient(circle at 80% 80%, rgba(67, 233, 123, 0.1) 0%, transparent 50%);
            pointer-events: none;
            z-index: -1;
        }

        .ai-edit-sidebar-header {
            background: var(--primary-gradient);
            color: white;
            padding: var(--spacing-sm) var(--spacing-lg);
            display: flex;
            justify-content: space-between;
            align-items: center;
            position: relative;
            overflow: hidden;
            z-index: 10;
            border-radius: var(--border-radius-xl) 0 0 0;
        }

        .ai-edit-sidebar-header::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background:
                radial-gradient(circle at 30% 30%, rgba(255, 255, 255, 0.1) 0%, transparent 50%),
                radial-gradient(circle at 70% 70%, rgba(255, 255, 255, 0.05) 0%, transparent 50%);
            animation: headerFloat 25s ease-in-out infinite;
        }

        .ai-edit-sidebar-header h4 {
            margin: 0;
            font-size: 1.125rem;
            font-weight: 700;
            flex: 1;
            position: relative;
            z-index: 1;
            text-shadow: 0 2px 8px rgba(0,0,0,0.3);
            letter-spacing: -0.01em;
        }

        .ai-current-slide-info {
            background: var(--glass-bg);
            backdrop-filter: blur(10px);
            border: 1px solid var(--glass-border);
            padding: 2px var(--spacing-xs);
            border-radius: var(--border-radius-md);
            font-size: 0.75rem;
            font-weight: 600;
            margin-right: var(--spacing-sm);
            color: white;
            text-shadow: 0 1px 3px rgba(0,0,0,0.3);
            position: relative;
            z-index: 1;
        }

        .ai-header-buttons {
            display: flex;
            gap: var(--spacing-sm);
            align-items: center;
            position: relative;
            z-index: 1;
        }

        .ai-outline-btn {
            background: var(--glass-bg);
            backdrop-filter: blur(10px);
            border: 1px solid var(--glass-border);
            color: white;
            padding: var(--spacing-xs) var(--spacing-sm);
            border-radius: var(--border-radius-sm);
            cursor: pointer;
            font-size: 0.875rem;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            position: relative;
            overflow: hidden;
        }

        .ai-outline-btn::before {
            content: '';
            position: absolute;
            top: 0;
            left: -100%;
            width: 100%;
            height: 100%;
            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
            transition: left 0.6s;
        }

        .ai-outline-btn:hover {
            background: rgba(255,255,255,0.2);
            border-color: rgba(255,255,255,0.4);
            transform: translateY(-1px);
            box-shadow: 0 4px 15px rgba(255, 255, 255, 0.2);
        }

        .ai-outline-btn:hover::before {
            left: 100%;
        }

        .ai-sidebar-resize-handle {
            position: absolute;
            left: 0;
            top: 0;
            width: 6px;
            height: 100%;
            background: transparent;
            cursor: ew-resize;
            z-index: 10;
            transition: background 0.3s ease;
        }

        .ai-sidebar-resize-handle:hover {
            background: var(--accent-gradient);
            opacity: 0.6;
        }

        .ai-edit-sidebar-close {
            background: var(--glass-bg);
            backdrop-filter: blur(10px);
            border: 1px solid var(--glass-border);
            color: white;
            font-size: 1.125rem;
            cursor: pointer;
            padding: var(--spacing-xs);
            border-radius: var(--border-radius-sm);
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            width: 32px;
            height: 32px;
            display: flex;
            align-items: center;
            justify-content: center;
            position: relative;
            overflow: hidden;
        }

        .ai-edit-sidebar-close::before {
            content: '';
            position: absolute;
            top: 0;
            left: -100%;
            width: 100%;
            height: 100%;
            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
            transition: left 0.6s;
        }

        .ai-edit-sidebar-close:hover {
            background: rgba(255, 255, 255, 0.2);
            border-color: rgba(255, 255, 255, 0.4);
            transform: translateY(-1px) scale(1.05);
            box-shadow: 0 4px 15px rgba(255, 255, 255, 0.2);
        }

        .ai-edit-sidebar-close:hover::before {
            left: 100%;
        }

        .ai-edit-content {
            flex: 1;
            display: flex;
            flex-direction: column;
            padding: var(--spacing-xl);
            overflow: hidden;
            position: relative;
        }



        .ai-chat-container {
            flex: 1;
            display: flex;
            flex-direction: column;
            overflow: hidden;
            position: relative;
        }

        .ai-chat-messages {
            flex: 1;
            overflow-y: auto;
            padding: var(--spacing-md);
            margin-bottom: var(--spacing-md);
            background: var(--glass-bg);
            backdrop-filter: blur(15px);
            border: 1px solid var(--glass-border);
            border-radius: var(--border-radius-md);
            box-shadow: 0 4px 15px rgba(31, 38, 135, 0.1);
            position: relative;
        }

        .ai-chat-messages::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background:
                radial-gradient(circle at 10% 10%, rgba(79, 172, 254, 0.05) 0%, transparent 50%),
                radial-gradient(circle at 90% 90%, rgba(67, 233, 123, 0.05) 0%, transparent 50%);
            pointer-events: none;
            z-index: -1;
        }

        .ai-message {
            margin: var(--spacing-sm) var(--spacing-md);
            padding: var(--spacing-sm) var(--spacing-md);
            border-radius: var(--border-radius-md);
            max-width: 85%;
            word-wrap: break-word;
            position: relative;
            backdrop-filter: blur(10px);
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        }

        .ai-message.user {
            background: var(--primary-gradient);
            color: white;
            margin-left: auto;
            margin-right: var(--spacing-md);
            box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
            border: 1px solid rgba(255, 255, 255, 0.2);
        }

        .ai-message.assistant {
            background: var(--glass-bg);
            color: var(--text-primary);
            border: 1px solid var(--glass-border);
            margin-right: auto;
            margin-left: var(--spacing-md);
            box-shadow: 0 4px 15px rgba(31, 38, 135, 0.1);
        }

        .ai-message.system {
            background: rgba(255, 255, 255, 0.1);
            color: var(--text-muted);
            font-style: italic;
            text-align: center;
            margin: var(--spacing-xs) var(--spacing-md);
            font-size: 0.75rem;
            border: 1px solid var(--glass-border);
            backdrop-filter: blur(10px);
        }

        .ai-message:hover {
            transform: translateY(-1px);
            box-shadow: 0 6px 20px rgba(31, 38, 135, 0.2);
        }

        .ai-input-container {
            display: flex;
            flex-direction: column;
            gap: var(--spacing-sm);
            position: relative;
            border: 2px solid transparent;
            border-radius: var(--border-radius-md);
            padding: var(--spacing-sm);
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        }

        .ai-input-container.drag-over {
            background-color: rgba(79, 172, 254, 0.1) !important;
            border-color: rgba(79, 172, 254, 0.6) !important;
            transform: scale(1.02) !important;
            box-shadow: 0 8px 25px rgba(79, 172, 254, 0.3) !important;
        }

        .ai-input-container.drag-over::before {
            content: '📷 释放图片到此处上传';
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: rgba(79, 172, 254, 0.9);
            color: white;
            padding: var(--spacing-sm) var(--spacing-md);
            border-radius: var(--border-radius-md);
            font-size: 0.875rem;
            font-weight: 600;
            z-index: 1000;
            pointer-events: none;
            box-shadow: 0 4px 15px rgba(79, 172, 254, 0.4);
        }

        /* 选中图像信息容器样式 */
        .ai-selected-image-container {
            background: var(--glass-bg);
            backdrop-filter: blur(10px);
            border: 1px solid var(--glass-border);
            border-radius: var(--border-radius-md);
            margin-bottom: var(--spacing-md);
            overflow: hidden;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        }

        .ai-selected-image-header {
            background: var(--primary-gradient);
            color: white;
            padding: var(--spacing-sm) var(--spacing-md);
            display: flex;
            justify-content: space-between;
            align-items: center;
            font-size: 0.875rem;
            font-weight: 600;
        }

        .ai-selected-image-header h6 {
            margin: 0;
            font-size: 0.875rem;
            font-weight: 600;
        }

        .ai-clear-selection-btn {
            background: rgba(255, 255, 255, 0.2);
            border: 1px solid rgba(255, 255, 255, 0.3);
            color: white;
            border-radius: var(--border-radius-sm);
            padding: 4px 8px;
            cursor: pointer;
            transition: all 0.2s ease;
            font-size: 0.75rem;
        }

        .ai-clear-selection-btn:hover {
            background: rgba(255, 255, 255, 0.3);
            border-color: rgba(255, 255, 255, 0.5);
            transform: scale(1.05);
        }

        .ai-selected-image-info {
            padding: var(--spacing-md);
            display: flex;
            gap: var(--spacing-md);
            align-items: flex-start;
        }

        .ai-selected-image-preview {
            flex-shrink: 0;
            width: 60px;
            height: 60px;
            border-radius: var(--border-radius-sm);
            overflow: hidden;
            border: 2px solid var(--glass-border);
        }

        .ai-selected-image-preview img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }

        .ai-selected-image-details {
            flex: 1;
            display: flex;
            flex-direction: column;
            gap: var(--spacing-xs);
        }

        .ai-image-detail-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            font-size: 0.8125rem;
        }

        .ai-detail-label {
            color: var(--text-secondary);
            font-weight: 500;
        }

        .ai-detail-value {
            color: var(--text-primary);
            font-weight: 600;
            text-align: right;
            max-width: 120px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }

        .ai-image-actions {
            padding: var(--spacing-sm) var(--spacing-md);
            border-top: 1px solid var(--glass-border);
            background: rgba(255, 255, 255, 0.02);
        }

        .ai-image-action-row {
            display: flex;
            gap: var(--spacing-xs);
            margin-bottom: var(--spacing-xs);
        }

        .ai-image-action-row:last-child {
            margin-bottom: 0;
        }

        .ai-regenerate-image-btn,
        .ai-replace-image-btn,
        .ai-delete-image-btn {
            flex: 1;
            border: none;
            color: white;
            padding: var(--spacing-sm) var(--spacing-md);
            border-radius: var(--border-radius-sm);
            font-size: 0.875rem;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            display: flex;
            align-items: center;
            justify-content: center;
            gap: var(--spacing-xs);
        }

        .ai-regenerate-image-btn {
            background: var(--accent-gradient);
        }

        .ai-regenerate-image-btn:hover {
            transform: translateY(-1px);
            box-shadow: 0 4px 15px rgba(67, 233, 123, 0.3);
        }

        .ai-replace-image-btn {
            background: var(--primary-gradient);
        }

        .ai-replace-image-btn:hover {
            transform: translateY(-1px);
            box-shadow: 0 4px 15px rgba(79, 172, 254, 0.3);
        }

        .ai-delete-image-btn {
            background: linear-gradient(135deg, #ff6b6b 0%, #ee5a52 100%);
            width: 100%;
        }

        .ai-delete-image-btn:hover {
            transform: translateY(-1px);
            box-shadow: 0 4px 15px rgba(255, 107, 107, 0.3);
        }

        .ai-regenerate-image-btn:active,
        .ai-replace-image-btn:active,
        .ai-delete-image-btn:active {
            transform: translateY(0);
        }

        .ai-input-box {
            width: 100%;
            min-height: 80px;
            max-height: 120px;
            padding: var(--spacing-sm);
            background: var(--glass-bg);
            backdrop-filter: blur(15px);
            border: 1px solid var(--glass-border);
            border-radius: var(--border-radius-md);
            resize: vertical;
            font-family: inherit;
            font-size: 0.875rem;
            color: var(--text-primary);
            outline: none;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            box-shadow: 0 2px 10px rgba(31, 38, 135, 0.1);
        }

        .ai-input-box:focus {
            border-color: rgba(79, 172, 254, 0.6);
            box-shadow: 0 0 0 3px rgba(79, 172, 254, 0.2), 0 4px 15px rgba(31, 38, 135, 0.2);
            transform: translateY(-1px);
        }

        .ai-input-box::placeholder {
            color: var(--text-muted);
            opacity: 0.8;
        }

        .ai-input-buttons {
            display: flex;
            gap: var(--spacing-sm);
            align-items: center;
            justify-content: flex-end;
        }

        .ai-send-btn {
            background: var(--primary-gradient);
            color: white;
            border: none;
            padding: var(--spacing-sm) var(--spacing-lg);
            border-radius: var(--border-radius-md);
            cursor: pointer;
            font-size: 0.875rem;
            font-weight: 600;
            transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
            position: relative;
            overflow: hidden;
            box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
            display: flex;
            align-items: center;
            gap: var(--spacing-xs);
        }

        .ai-send-btn::before {
            content: '';
            position: absolute;
            top: 0;
            left: -100%;
            width: 100%;
            height: 100%;
            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
            transition: left 0.6s;
        }

        .ai-send-btn:hover {
            transform: translateY(-2px) scale(1.02);
            box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
        }

        .ai-send-btn:hover::before {
            left: 100%;
        }

        .ai-send-btn:disabled {
            background: var(--text-muted);
            cursor: not-allowed;
            transform: none;
            box-shadow: 0 2px 8px rgba(113, 128, 150, 0.2);
        }

        .ai-send-btn:disabled::before {
            display: none;
        }

        .ai-clear-context-btn {
            background: var(--glass-bg);
            backdrop-filter: blur(15px);
            border: 1px solid var(--glass-border);
            color: var(--text-secondary);
            padding: var(--spacing-sm);
            border-radius: var(--border-radius-md);
            cursor: pointer;
            font-size: 0.875rem;
            transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
            width: 44px;
            height: 44px;
            display: flex;
            align-items: center;
            justify-content: center;
            position: relative;
            overflow: hidden;
            box-shadow: 0 2px 10px rgba(31, 38, 135, 0.1);
        }

        .ai-clear-context-btn::before {
            content: '';
            position: absolute;
            top: 0;
            left: -100%;
            width: 100%;
            height: 100%;
            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
            transition: left 0.6s;
        }

        .ai-clear-context-btn:hover {
            background: rgba(220, 53, 69, 0.1);
            border-color: rgba(220, 53, 69, 0.3);
            color: #dc3545;
            transform: translateY(-2px) scale(1.05);
            box-shadow: 0 4px 15px rgba(220, 53, 69, 0.2);
        }

        .ai-clear-context-btn:hover::before {
            left: 100%;
        }

        /* AI等待动画样式 - 优化设计 */
        .ai-waiting {
            display: flex;
            align-items: center;
            opacity: 0.9;
            padding: var(--spacing-sm);
            background: var(--glass-bg);
            backdrop-filter: blur(10px);
            border: 1px solid var(--glass-border);
            border-radius: var(--border-radius-md);
            margin: var(--spacing-sm) var(--spacing-md);
            box-shadow: 0 2px 10px rgba(31, 38, 135, 0.1);
        }

        .ai-typing-indicator {
            display: flex;
            gap: var(--spacing-xs);
            margin-right: var(--spacing-sm);
        }

        .ai-typing-indicator span {
            width: 10px;
            height: 10px;
            border-radius: 50%;
            background: var(--accent-gradient);
            animation: typing 1.4s infinite ease-in-out;
            box-shadow: 0 2px 4px rgba(79, 172, 254, 0.3);
        }

        .ai-typing-indicator span:nth-child(1) {
            animation-delay: -0.32s;
        }

        .ai-typing-indicator span:nth-child(2) {
            animation-delay: -0.16s;
        }

        .ai-typing-indicator span:nth-child(3) {
            animation-delay: 0s;
        }

        @keyframes typing {
            0%, 80%, 100% {
                transform: scale(0.8);
                opacity: 0.5;
            }
            40% {
                transform: scale(1.2);
                opacity: 1;
            }
        }

        /* 侧栏遮罩层 - 优化设计 */
        .ai-sidebar-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.4);
            backdrop-filter: blur(8px);
            z-index: 1999;
            opacity: 0;
            visibility: hidden;
            transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
        }

        .ai-sidebar-overlay.show {
            opacity: 1;
            visibility: visible;
        }

        /* AI图片上传按钮样式 */
        .ai-image-upload-btn {
            background: var(--glass-bg);
            backdrop-filter: blur(15px);
            border: 1px solid var(--glass-border);
            color: var(--text-secondary);
            padding: var(--spacing-sm);
            border-radius: var(--border-radius-md);
            cursor: pointer;
            font-size: 0.875rem;
            transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
            width: 44px;
            height: 44px;
            display: flex;
            align-items: center;
            justify-content: center;
            position: relative;
            overflow: hidden;
            box-shadow: 0 2px 10px rgba(31, 38, 135, 0.1);
        }

        .ai-image-upload-btn::before {
            content: '';
            position: absolute;
            top: 0;
            left: -100%;
            width: 100%;
            height: 100%;
            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
            transition: left 0.6s;
        }

        .ai-image-upload-btn:hover {
            background: rgba(79, 172, 254, 0.1);
            border-color: rgba(79, 172, 254, 0.3);
            color: rgba(79, 172, 254, 0.8);
            transform: translateY(-2px) scale(1.05);
            box-shadow: 0 4px 15px rgba(79, 172, 254, 0.2);
        }

        .ai-image-upload-btn:hover::before {
            left: 100%;
        }

        .ai-image-upload-btn.has-images {
            background: rgba(67, 233, 123, 0.1);
            border-color: rgba(67, 233, 123, 0.3);
            color: rgba(67, 233, 123, 0.8);
        }

        .ai-image-upload-btn.has-images::after {
            content: attr(data-count);
            position: absolute;
            top: -6px;
            right: -6px;
            background: #28a745;
            color: white;
            border-radius: 50%;
            width: 18px;
            height: 18px;
            font-size: 0.625rem;
            display: flex;
            align-items: center;
            justify-content: center;
            font-weight: bold;
            box-shadow: 0 2px 4px rgba(40, 167, 69, 0.3);
        }

        /* AI重新生成按钮样式 */
        .ai-regenerate-btn {
            background: var(--glass-bg);
            backdrop-filter: blur(15px);
            border: 1px solid var(--glass-border);
            color: var(--text-secondary);
            padding: var(--spacing-sm);
            border-radius: var(--border-radius-md);
            cursor: pointer;
            font-size: 0.875rem;
            transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
            width: 44px;
            height: 44px;
            display: flex;
            align-items: center;
            justify-content: center;
            position: relative;
            overflow: hidden;
            box-shadow: 0 2px 10px rgba(31, 38, 135, 0.1);
        }

        .ai-regenerate-btn::before {
            content: '';
            position: absolute;
            top: 0;
            left: -100%;
            width: 100%;
            height: 100%;
            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
            transition: left 0.6s;
        }

        .ai-regenerate-btn:hover {
            background: rgba(255, 193, 7, 0.1);
            border-color: rgba(255, 193, 7, 0.3);
            color: rgba(255, 193, 7, 0.8);
            transform: translateY(-2px) scale(1.05);
            box-shadow: 0 4px 15px rgba(255, 193, 7, 0.2);
        }

        .ai-regenerate-btn:hover::before {
            left: 100%;
        }

        .ai-regenerate-btn:hover i {
            animation: spin 1s linear infinite;
        }

        /* 快速编辑模式样式 */
        .quick-edit-mode .slide-frame {
            cursor: pointer;
        }

        .quick-edit-overlay {
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(79, 172, 254, 0.05);
            border: 2px dashed rgba(79, 172, 254, 0.3);
            border-radius: var(--border-radius-md);
            display: none;
            z-index: 10;
            pointer-events: none;
        }

        .quick-edit-mode .quick-edit-overlay {
            display: block;
        }

        .quick-edit-overlay::before {
            content: '💡 点击文本直接编辑 | Enter保存 | ESC取消 | 再次点击修改退出';
            position: absolute;
            top: 10px;
            left: 50%;
            transform: translateX(-50%);
            background: rgba(79, 172, 254, 0.9);
            color: white;
            padding: var(--spacing-xs) var(--spacing-sm);
            border-radius: var(--border-radius-sm);
            font-size: 0.60rem;
            font-weight: 500;
            white-space: nowrap;
            box-shadow: 0 2px 8px rgba(79, 172, 254, 0.3);
            animation: fadeInDown 0.5s ease;
        }

        @keyframes fadeInDown {
            from {
                opacity: 0;
                transform: translateX(-50%) translateY(-10px);
            }
            to {
                opacity: 1;
                transform: translateX(-50%) translateY(0);
            }
        }

        /* 可编辑元素高亮样式 */
        .quick-edit-highlight {
            outline: 2px solid rgba(67, 233, 123, 0.6) !important;
            outline-offset: 2px !important;
            background: rgba(67, 233, 123, 0.1) !important;
            cursor: text !important;
            transition: all 0.3s ease !important;
            position: relative !important;
        }

        .quick-edit-highlight:hover {
            outline-color: rgba(67, 233, 123, 0.8) !important;
            background: rgba(67, 233, 123, 0.2) !important;
            transform: scale(1.02) !important;
        }

        .quick-edit-highlight::before {
            content: '✏️';
            position: absolute !important;
            top: -8px !important;
            right: -8px !important;
            background: rgba(67, 233, 123, 0.9) !important;
            color: white !important;
            border-radius: 50% !important;
            width: 20px !important;
            height: 20px !important;
            display: flex !important;
            align-items: center !important;
            justify-content: center !important;
            font-size: 10px !important;
            z-index: 1000 !important;
            box-shadow: 0 2px 4px rgba(67, 233, 123, 0.3) !important;
        }

        /* 直接编辑状态样式 */
        .direct-editing {
            outline: 2px solid #4facfe !important;
            outline-offset: 2px !important;
            background: rgba(79, 172, 254, 0.1) !important;
            border-radius: 4px !important;
            padding: 2px 4px !important;
            transition: all 0.3s ease !important;
            position: relative !important;
        }

        /* 魔术棒按钮样式 */
        .magic-wand-btn {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
            color: white !important;
            border: none !important;
            border-radius: 50% !important;
            width: 28px !important;
            height: 28px !important;
            cursor: pointer !important;
            margin-left: 8px !important;
            display: flex !important;
            align-items: center !important;
            justify-content: center !important;
            font-size: 14px !important;
            transition: all 0.3s ease !important;
            opacity: 0.7 !important;
            position: relative !important;
            overflow: hidden !important;
            box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3) !important;
        }

        .magic-wand-btn::before {
            content: '' !important;
            position: absolute !important;
            top: 0 !important;
            left: -100% !important;
            width: 100% !important;
            height: 100% !important;
            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent) !important;
            transition: left 0.6s !important;
        }

        .magic-wand-btn:hover {
            opacity: 1 !important;
            transform: translateY(-2px) scale(1.1) !important;
            box-shadow: 0 4px 15px rgba(102, 126, 234, 0.5) !important;
            background: linear-gradient(135deg, #7c8cff 0%, #8a5cb8 100%) !important;
        }

        .magic-wand-btn:hover::before {
            left: 100% !important;
        }

        .magic-wand-btn:active {
            transform: translateY(0) scale(1.05) !important;
        }

        .magic-wand-btn:disabled {
            opacity: 0.5 !important;
            cursor: not-allowed !important;
            transform: none !important;
            box-shadow: 0 2px 8px rgba(102, 126, 234, 0.2) !important;
        }

        .magic-wand-btn:disabled:hover {
            transform: none !important;
            box-shadow: 0 2px 8px rgba(102, 126, 234, 0.2) !important;
        }

        /* 删除要点按钮样式 */
        .delete-bullet-btn {
            background: #dc3545 !important;
            color: white !important;
            border: none !important;
            border-radius: 50% !important;
            width: 28px !important;
            height: 28px !important;
            cursor: pointer !important;
            margin-left: 4px !important;
            display: flex !important;
            align-items: center !important;
            justify-content: center !important;
            font-size: 12px !important;
            transition: all 0.3s ease !important;
            opacity: 0.7 !important;
            box-shadow: 0 2px 8px rgba(220, 53, 69, 0.3) !important;
        }

        .delete-bullet-btn:hover {
            opacity: 1 !important;
            transform: translateY(-2px) scale(1.1) !important;
            box-shadow: 0 4px 15px rgba(220, 53, 69, 0.5) !important;
            background: #c82333 !important;
        }

        .delete-bullet-btn:active {
            transform: translateY(0) scale(1.05) !important;
        }

        /* 要点项悬停效果 */
        .bullet-point-item:hover .delete-bullet-btn {
            opacity: 1 !important;
        }

        .bullet-point-item:hover {
            background: rgba(0, 0, 0, 0.02) !important;
            border-radius: 6px !important;
            transform: translateX(2px) !important;
        }

        /* 增强所有要点按钮样式 */
        .enhance-all-btn {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
            color: white !important;
            border: none !important;
            padding: 8px 16px !important;
            border-radius: 6px !important;
            cursor: pointer !important;
            font-size: 14px !important;
            transition: all 0.3s ease !important;
            display: flex !important;
            align-items: center !important;
            gap: 6px !important;
            box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3) !important;
            position: relative !important;
            overflow: hidden !important;
        }

        .enhance-all-btn::before {
            content: '' !important;
            position: absolute !important;
            top: 0 !important;
            left: -100% !important;
            width: 100% !important;
            height: 100% !important;
            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.3), transparent) !important;
            transition: left 0.6s !important;
        }

        .enhance-all-btn:hover {
            transform: translateY(-2px) scale(1.02) !important;
            box-shadow: 0 4px 15px rgba(102, 126, 234, 0.5) !important;
            background: linear-gradient(135deg, #7c8cff 0%, #8a5cb8 100%) !important;
        }

        .enhance-all-btn:hover::before {
            left: 100% !important;
        }

        .enhance-all-btn:active {
            transform: translateY(0) scale(1.0) !important;
        }

        .enhance-all-btn:disabled {
            opacity: 0.6 !important;
            cursor: not-allowed !important;
            transform: none !important;
            box-shadow: 0 2px 8px rgba(102, 126, 234, 0.2) !important;
        }

        .enhance-all-btn:disabled:hover {
            transform: none !important;
            box-shadow: 0 2px 8px rgba(102, 126, 234, 0.2) !important;
        }

        .direct-editing::before {
            content: '📝 正在编辑... (Enter保存 / ESC取消)';
            position: absolute !important;
            top: -30px !important;
            left: 0 !important;
            background: rgba(79, 172, 254, 0.9) !important;
            color: white !important;
            padding: 4px 8px !important;
            border-radius: 4px !important;
            font-size: 11px !important;
            font-weight: 600 !important;
            white-space: nowrap !important;
            z-index: 1001 !important;
            box-shadow: 0 2px 8px rgba(79, 172, 254, 0.3) !important;
            animation: fadeInDown 0.3s ease !important;
        }

        .direct-editing:focus {
            outline-color: #2980b9 !important;
            background: rgba(79, 172, 254, 0.15) !important;
        }

        /* 内联编辑器样式 */
        .inline-editor {
            position: absolute;
            background: white;
            border: 2px solid rgba(79, 172, 254, 0.6);
            border-radius: var(--border-radius-md);
            box-shadow: 0 8px 25px rgba(31, 38, 135, 0.3);
            z-index: 2000;
            min-width: 200px;
            max-width: 500px;
            padding: var(--spacing-sm);
            backdrop-filter: blur(15px);
        }

        .inline-editor-input {
            width: 100%;
            border: none;
            outline: none;
            font-family: inherit;
            font-size: inherit;
            color: inherit;
            background: transparent;
            resize: none;
            min-height: 30px;
            padding: var(--spacing-xs);
        }

        .inline-editor-toolbar {
            display: flex;
            gap: var(--spacing-xs);
            align-items: center;
            justify-content: flex-end;
            margin-top: var(--spacing-xs);
            padding-top: var(--spacing-xs);
            border-top: 1px solid rgba(79, 172, 254, 0.2);
        }

        .inline-editor-btn {
            background: rgba(79, 172, 254, 0.1);
            border: 1px solid rgba(79, 172, 254, 0.3);
            color: rgba(79, 172, 254, 0.8);
            padding: var(--spacing-xs) var(--spacing-sm);
            border-radius: var(--border-radius-sm);
            cursor: pointer;
            font-size: 0.75rem;
            transition: all 0.3s ease;
        }

        .inline-editor-btn:hover {
            background: rgba(79, 172, 254, 0.2);
            border-color: rgba(79, 172, 254, 0.5);
            color: rgba(79, 172, 254, 1);
        }

        .inline-editor-btn.primary {
            background: rgba(67, 233, 123, 0.1);
            border-color: rgba(67, 233, 123, 0.3);
            color: rgba(67, 233, 123, 0.8);
        }

        .inline-editor-btn.primary:hover {
            background: rgba(67, 233, 123, 0.2);
            border-color: rgba(67, 233, 123, 0.5);
            color: rgba(67, 233, 123, 1);
        }

        @keyframes spin {
            from { transform: rotate(0deg); }
            to { transform: rotate(360deg); }
        }



        @keyframes fadeIn {
            from {
                opacity: 0;
                transform: translateY(-5px);
            }
            to {
                opacity: 1;
                transform: translateY(0);
            }
        }

        /* 图片选择菜单样式 */
        .image-select-menu {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.5);
            backdrop-filter: blur(5px);
            z-index: 9999;
            display: flex;
            align-items: center;
            justify-content: center;
            animation: fadeInOverlay 0.3s ease-out;
        }

        .image-select-content {
            background: var(--glass-bg);
            backdrop-filter: blur(20px);
            border: 1px solid var(--glass-border);
            border-radius: var(--border-radius-xl);
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
            width: 400px;
            max-width: 90vw;
            overflow: hidden;
            animation: slideInPreview 0.4s cubic-bezier(0.4, 0, 0.2, 1);
        }

        .image-select-header {
            background: var(--primary-gradient);
            color: white;
            padding: var(--spacing-md) var(--spacing-lg);
            display: flex;
            justify-content: space-between;
            align-items: center;
            position: relative;
            overflow: hidden;
        }

        .image-select-header::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background:
                radial-gradient(circle at 20% 20%, rgba(255, 255, 255, 0.1) 0%, transparent 50%),
                radial-gradient(circle at 80% 80%, rgba(255, 255, 255, 0.05) 0%, transparent 50%);
            pointer-events: none;
        }

        .image-select-header h4 {
            margin: 0;
            font-size: 1.125rem;
            font-weight: 600;
            position: relative;
            z-index: 1;
            display: flex;
            align-items: center;
            gap: var(--spacing-xs);
        }

        .image-select-close {
            background: var(--glass-bg);
            backdrop-filter: blur(10px);
            border: 1px solid var(--glass-border);
            color: white;
            width: 32px;
            height: 32px;
            border-radius: 50%;
            cursor: pointer;
            font-size: 0.875rem;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            display: flex;
            align-items: center;
            justify-content: center;
            position: relative;
            z-index: 1;
        }

        .image-select-close:hover {
            background: rgba(255, 255, 255, 0.2);
            border-color: rgba(255, 255, 255, 0.4);
            transform: scale(1.1);
        }

        .image-select-options {
            padding: var(--spacing-lg);
            display: flex;
            flex-direction: column;
            gap: var(--spacing-md);
        }

        .image-select-option {
            background: var(--glass-bg);
            backdrop-filter: blur(15px);
            border: 1px solid var(--glass-border);
            border-radius: var(--border-radius-md);
            padding: var(--spacing-md);
            cursor: pointer;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            text-align: left;
            display: flex;
            flex-direction: column;
            gap: var(--spacing-xs);
            position: relative;
            overflow: hidden;
        }

        .image-select-option::before {
            content: '';
            position: absolute;
            top: 0;
            left: -100%;
            width: 100%;
            height: 100%;
            background: linear-gradient(90deg, transparent, rgba(79, 172, 254, 0.1), transparent);
            transition: left 0.6s;
        }

        .image-select-option:hover {
            background: rgba(79, 172, 254, 0.1);
            border-color: rgba(79, 172, 254, 0.3);
            transform: translateY(-2px);
            box-shadow: 0 4px 15px rgba(79, 172, 254, 0.2);
        }

        .image-select-option:hover::before {
            left: 100%;
        }

        .image-select-option i {
            font-size: 1.5rem;
            color: rgba(79, 172, 254, 0.8);
            margin-bottom: var(--spacing-xs);
        }

        .image-select-option span {
            font-size: 1rem;
            font-weight: 600;
            color: var(--text-primary);
            position: relative;
            z-index: 1;
        }

        .image-select-option small {
            font-size: 0.8125rem;
            color: var(--text-muted);
            position: relative;
            z-index: 1;
        }

        /* 图床选择器样式 */
        .image-library-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.8);
            backdrop-filter: blur(10px);
            z-index: 10001;
            display: flex;
            align-items: center;
            justify-content: center;
            animation: fadeInOverlay 0.3s ease-out;
        }

        .image-library-container {
            background: var(--glass-bg);
            backdrop-filter: blur(20px);
            border: 1px solid var(--glass-border);
            border-radius: var(--border-radius-xl);
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
            width: 80vw;
            max-width: 1000px;
            height: 80vh;
            max-height: 800px;
            display: flex;
            flex-direction: column;
            overflow: hidden;
            animation: slideInPreview 0.4s cubic-bezier(0.4, 0, 0.2, 1);
        }

        .image-library-header {
            background: var(--primary-gradient);
            color: white;
            padding: var(--spacing-md) var(--spacing-lg);
            display: flex;
            justify-content: space-between;
            align-items: center;
            position: relative;
            overflow: hidden;
        }

        .image-library-header::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background:
                radial-gradient(circle at 20% 20%, rgba(255, 255, 255, 0.1) 0%, transparent 50%),
                radial-gradient(circle at 80% 80%, rgba(255, 255, 255, 0.05) 0%, transparent 50%);
            pointer-events: none;
        }

        .image-library-info {
            position: relative;
            z-index: 1;
        }

        .image-library-info h4 {
            margin: 0 0 4px 0;
            font-size: 1.25rem;
            font-weight: 600;
            display: flex;
            align-items: center;
            gap: var(--spacing-xs);
        }

        .image-library-info p {
            margin: 0;
            font-size: 0.875rem;
            opacity: 0.9;
        }

        .image-library-close {
            background: var(--glass-bg);
            backdrop-filter: blur(10px);
            border: 1px solid var(--glass-border);
            color: white;
            width: 40px;
            height: 40px;
            border-radius: 50%;
            cursor: pointer;
            font-size: 1.125rem;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            display: flex;
            align-items: center;
            justify-content: center;
            position: relative;
            z-index: 1;
        }

        .image-library-close:hover {
            background: rgba(255, 255, 255, 0.2);
            border-color: rgba(255, 255, 255, 0.4);
            transform: scale(1.1);
        }

        .image-library-content {
            flex: 1;
            padding: var(--spacing-lg);
            overflow-y: auto;
            position: relative;
        }

        .image-library-search {
            margin-bottom: var(--spacing-md);
            position: sticky;
            top: 0;
            z-index: 10;
            background: var(--glass-bg);
            backdrop-filter: blur(20px);
            padding: var(--spacing-sm) 0;
            border-radius: var(--border-radius-lg);
        }

        .search-input-group {
            position: relative;
            display: flex;
            align-items: center;
        }

        .search-input-group i.fa-search {
            position: absolute;
            left: var(--spacing-sm);
            color: var(--text-muted);
            z-index: 1;
        }

        .search-input-group input {
            width: 100%;
            padding: var(--spacing-sm) var(--spacing-xl) var(--spacing-sm) 2.5rem;
            border: 1px solid var(--glass-border);
            border-radius: var(--border-radius-lg);
            background: rgba(255, 255, 255, 0.1);
            color: var(--text-primary);
            font-size: 0.875rem;
            transition: all 0.3s ease;
        }

        .search-input-group input:focus {
            outline: none;
            border-color: var(--primary-color);
            background: rgba(255, 255, 255, 0.15);
            box-shadow: 0 0 0 3px rgba(74, 144, 226, 0.1);
        }

        .search-input-group input::placeholder {
            color: var(--text-muted);
        }

        .search-clear-btn {
            position: absolute;
            right: var(--spacing-sm);
            background: none;
            border: none;
            color: var(--text-muted);
            cursor: pointer;
            padding: var(--spacing-xs);
            border-radius: 50%;
            transition: all 0.2s ease;
            z-index: 1;
        }

        .search-clear-btn:hover {
            background: rgba(255, 255, 255, 0.1);
            color: var(--text-primary);
        }

        .image-library-loading {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            text-align: center;
            color: var(--text-primary);
        }

        .image-library-loading i {
            font-size: 2rem;
            margin-bottom: var(--spacing-sm);
            color: rgba(79, 172, 254, 0.8);
        }

        .image-library-loading p {
            margin: 0;
            font-size: 0.875rem;
            opacity: 0.8;
        }

        .image-library-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
            gap: var(--spacing-md);
            padding: var(--spacing-sm);
        }

        .image-library-item {
            background: var(--glass-bg);
            backdrop-filter: blur(15px);
            border: 2px solid var(--glass-border);
            border-radius: var(--border-radius-md);
            overflow: hidden;
            cursor: pointer;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            position: relative;
            aspect-ratio: 1;
        }

        .image-library-item:hover {
            transform: scale(1.05);
            border-color: rgba(79, 172, 254, 0.6);
            box-shadow: 0 4px 15px rgba(79, 172, 254, 0.3);
        }

        .image-library-item.selected {
            border-color: rgba(67, 233, 123, 0.8);
            background: rgba(67, 233, 123, 0.1);
            transform: scale(1.02);
        }

        .image-library-item img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }

        .image-library-item .image-info {
            position: absolute;
            bottom: 0;
            left: 0;
            right: 0;
            background: rgba(0, 0, 0, 0.8);
            color: white;
            padding: var(--spacing-xs);
            font-size: 0.75rem;
            opacity: 0;
            transition: opacity 0.3s ease;
        }

        .image-library-item:hover .image-info {
            opacity: 1;
        }

        .image-library-item .selection-indicator {
            position: absolute;
            top: 8px;
            right: 8px;
            width: 24px;
            height: 24px;
            background: rgba(67, 233, 123, 0.9);
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            color: white;
            font-size: 0.875rem;
            opacity: 0;
            transform: scale(0.8);
            transition: all 0.3s ease;
        }

        .image-library-item.selected .selection-indicator {
            opacity: 1;
            transform: scale(1);
        }

        .image-library-empty {
            text-align: center;
            color: var(--text-muted);
            padding: var(--spacing-xl);
        }

        .image-library-empty i {
            font-size: 3rem;
            margin-bottom: var(--spacing-md);
            opacity: 0.5;
        }

        .image-library-empty p {
            margin: 0 0 var(--spacing-xs) 0;
            font-size: 1.125rem;
            font-weight: 600;
        }

        .image-library-empty small {
            font-size: 0.875rem;
            opacity: 0.8;
        }

        .image-library-pagination {
            background: var(--glass-bg);
            backdrop-filter: blur(15px);
            border-top: 1px solid var(--glass-border);
            padding: var(--spacing-md) var(--spacing-lg);
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .pagination-info {
            color: var(--text-muted);
            font-size: 0.875rem;
        }

        .pagination-controls {
            display: flex;
            gap: var(--spacing-sm);
        }

        .pagination-btn {
            background: var(--glass-bg);
            backdrop-filter: blur(15px);
            border: 1px solid var(--glass-border);
            color: var(--text-primary);
            padding: var(--spacing-xs) var(--spacing-sm);
            border-radius: var(--border-radius-md);
            cursor: pointer;
            transition: all 0.3s ease;
            font-size: 0.875rem;
            display: flex;
            align-items: center;
            gap: var(--spacing-xs);
        }

        .pagination-btn:hover:not(:disabled) {
            background: rgba(255, 255, 255, 0.2);
            border-color: rgba(255, 255, 255, 0.4);
            transform: translateY(-1px);
        }

        .pagination-btn:disabled {
            opacity: 0.5;
            cursor: not-allowed;
            transform: none;
        }

        .image-library-actions {
            background: var(--glass-bg);
            backdrop-filter: blur(15px);
            border-top: 1px solid var(--glass-border);
            padding: var(--spacing-md) var(--spacing-lg);
            display: flex;
            gap: var(--spacing-md);
            justify-content: flex-end;
        }

        .image-library-action {
            background: var(--glass-bg);
            backdrop-filter: blur(15px);
            border: 1px solid var(--glass-border);
            color: var(--text-primary);
            padding: var(--spacing-sm) var(--spacing-md);
            border-radius: var(--border-radius-md);
            cursor: pointer;
            font-size: 0.875rem;
            font-weight: 500;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            display: flex;
            align-items: center;
            gap: var(--spacing-xs);
            min-width: 120px;
            justify-content: center;
        }

        .image-library-action:hover:not(:disabled) {
            background: rgba(79, 172, 254, 0.1);
            border-color: rgba(79, 172, 254, 0.3);
            color: rgba(79, 172, 254, 0.8);
            transform: translateY(-2px);
        }

        .image-library-action:disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }

        .image-library-action.secondary {
            background: rgba(108, 117, 125, 0.1);
            border-color: rgba(108, 117, 125, 0.3);
        }

        .image-library-action.secondary:hover {
            background: rgba(108, 117, 125, 0.2);
            border-color: rgba(108, 117, 125, 0.4);
            color: rgba(108, 117, 125, 0.9);
        }

        /* 响应式设计 - 图片选择器 */
        @media (max-width: 768px) {
            .image-select-content {
                width: 95vw;
                margin: 0 10px;
            }

            .image-select-options {
                padding: var(--spacing-md);
                gap: var(--spacing-sm);
            }

            .image-select-option {
                padding: var(--spacing-sm);
            }

            .image-library-container {
                width: 95vw;
                height: 90vh;
                margin: 0 10px;
            }

            .image-library-grid {
                grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
                gap: var(--spacing-sm);
            }

            .image-library-actions {
                padding: var(--spacing-sm);
                flex-direction: column;
                gap: var(--spacing-sm);
            }

            .image-library-action {
                width: 100%;
                min-width: auto;
            }
        }

        /* 全屏图片预览样式 */
        .image-preview-overlay {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.9);
            backdrop-filter: blur(10px);
            z-index: 10000;
            display: flex;
            align-items: center;
            justify-content: center;
            animation: fadeInOverlay 0.3s ease-out;
        }

        @keyframes fadeInOverlay {
            from {
                opacity: 0;
            }
            to {
                opacity: 1;
            }
        }

        .image-preview-container {
            max-width: 90vw;
            max-height: 90vh;
            background: var(--glass-bg);
            backdrop-filter: blur(20px);
            border: 1px solid var(--glass-border);
            border-radius: var(--border-radius-xl);
            box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
            display: flex;
            flex-direction: column;
            overflow: hidden;
            animation: slideInPreview 0.4s cubic-bezier(0.4, 0, 0.2, 1);
        }

        @keyframes slideInPreview {
            from {
                opacity: 0;
                transform: scale(0.8) translateY(20px);
            }
            to {
                opacity: 1;
                transform: scale(1) translateY(0);
            }
        }

        .image-preview-header {
            background: var(--primary-gradient);
            color: white;
            padding: var(--spacing-md) var(--spacing-lg);
            display: flex;
            justify-content: space-between;
            align-items: center;
            position: relative;
            overflow: hidden;
        }

        .image-preview-header::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background:
                radial-gradient(circle at 20% 20%, rgba(255, 255, 255, 0.1) 0%, transparent 50%),
                radial-gradient(circle at 80% 80%, rgba(255, 255, 255, 0.05) 0%, transparent 50%);
            pointer-events: none;
        }

        .image-preview-info {
            position: relative;
            z-index: 1;
        }

        .image-preview-info h4 {
            margin: 0 0 4px 0;
            font-size: 1.125rem;
            font-weight: 600;
        }

        .image-preview-info p {
            margin: 0;
            font-size: 0.875rem;
            opacity: 0.9;
        }

        .image-preview-close {
            background: var(--glass-bg);
            backdrop-filter: blur(10px);
            border: 1px solid var(--glass-border);
            color: white;
            width: 40px;
            height: 40px;
            border-radius: 50%;
            cursor: pointer;
            font-size: 1.125rem;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            display: flex;
            align-items: center;
            justify-content: center;
            position: relative;
            z-index: 1;
            overflow: hidden;
        }

        .image-preview-close::before {
            content: '';
            position: absolute;
            top: 0;
            left: -100%;
            width: 100%;
            height: 100%;
            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
            transition: left 0.6s;
        }

        .image-preview-close:hover {
            background: rgba(255, 255, 255, 0.2);
            border-color: rgba(255, 255, 255, 0.4);
            transform: scale(1.1);
            box-shadow: 0 4px 15px rgba(255, 255, 255, 0.2);
        }

        .image-preview-close:hover::before {
            left: 100%;
        }

        .image-preview-content {
            flex: 1;
            display: flex;
            align-items: center;
            justify-content: center;
            position: relative;
            min-height: 400px;
            max-height: 70vh;
            overflow: hidden;
            background: rgba(0, 0, 0, 0.3);
        }

        .image-preview-content img {
            max-width: 100%;
            max-height: 100%;
            object-fit: contain;
            border-radius: var(--border-radius-md);
            box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
            transition: transform 0.3s ease;
        }

        .image-preview-content img:hover {
            transform: scale(1.02);
        }

        .image-preview-loading {
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            text-align: center;
            color: white;
        }

        .image-preview-loading i {
            font-size: 2rem;
            margin-bottom: var(--spacing-sm);
            color: rgba(79, 172, 254, 0.8);
        }

        .image-preview-loading p {
            margin: 0;
            font-size: 0.875rem;
            opacity: 0.8;
        }

        .image-preview-actions {
            background: var(--glass-bg);
            backdrop-filter: blur(15px);
            border-top: 1px solid var(--glass-border);
            padding: var(--spacing-md) var(--spacing-lg);
            display: flex;
            gap: var(--spacing-md);
            justify-content: center;
        }

        .image-preview-action {
            background: var(--glass-bg);
            backdrop-filter: blur(15px);
            border: 1px solid var(--glass-border);
            color: var(--text-primary);
            padding: var(--spacing-sm) var(--spacing-md);
            border-radius: var(--border-radius-md);
            cursor: pointer;
            font-size: 0.875rem;
            font-weight: 500;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            display: flex;
            align-items: center;
            gap: var(--spacing-xs);
            position: relative;
            overflow: hidden;
            min-width: 120px;
            justify-content: center;
        }

        .image-preview-action::before {
            content: '';
            position: absolute;
            top: 0;
            left: -100%;
            width: 100%;
            height: 100%;
            background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
            transition: left 0.6s;
        }

        .image-preview-action:hover {
            background: rgba(79, 172, 254, 0.1);
            border-color: rgba(79, 172, 254, 0.3);
            color: rgba(79, 172, 254, 0.8);
            transform: translateY(-2px);
            box-shadow: 0 4px 15px rgba(79, 172, 254, 0.2);
        }

        .image-preview-action:hover::before {
            left: 100%;
        }

        .image-preview-action.danger:hover {
            background: rgba(220, 53, 69, 0.1);
            border-color: rgba(220, 53, 69, 0.3);
            color: #dc3545;
            box-shadow: 0 4px 15px rgba(220, 53, 69, 0.2);
        }

        /* 响应式设计 */
        @media (max-width: 768px) {
            .image-preview-container {
                max-width: 95vw;
                max-height: 95vh;
            }

            .image-preview-header {
                padding: var(--spacing-sm) var(--spacing-md);
            }

            .image-preview-info h4 {
                font-size: 1rem;
            }

            .image-preview-info p {
                font-size: 0.75rem;
            }

            .image-preview-actions {
                padding: var(--spacing-sm) var(--spacing-md);
                flex-wrap: wrap;
            }

            .image-preview-action {
                flex: 1;
                min-width: 80px;
                font-size: 0.75rem;
                padding: var(--spacing-xs) var(--spacing-sm);
            }
        }

        .ai-upload-progress {
            margin-top: var(--spacing-md);
            padding: var(--spacing-sm);
            background: rgba(79, 172, 254, 0.05);
            border-radius: var(--border-radius-sm);
            border: 1px solid var(--glass-border);
        }

        .ai-progress-bar {
            width: 100%;
            height: 8px;
            background: rgba(79, 172, 254, 0.2);
            border-radius: 4px;
            overflow: hidden;
            margin-bottom: var(--spacing-xs);
        }

        .ai-progress-fill {
            height: 100%;
            background: var(--accent-gradient);
            border-radius: 4px;
            transition: width 0.3s ease;
            width: 0%;
        }

        .ai-progress-text {
            font-size: 0.75rem;
            color: var(--text-secondary);
            text-align: center;
        }

        .ai-uploaded-images {
            margin-top: var(--spacing-sm);
            display: flex;
            flex-wrap: wrap;
            gap: var(--spacing-xs);
            max-height: 120px;
            overflow-y: auto;
            padding: var(--spacing-xs);
            background: rgba(79, 172, 254, 0.05);
            border-radius: var(--border-radius-sm);
            border: 1px solid var(--glass-border);
        }

        .ai-uploaded-images:empty {
            display: none;
        }

        .ai-uploaded-image {
            position: relative;
            width: 50px;
            height: 50px;
            border-radius: var(--border-radius-sm);
            overflow: hidden;
            border: 2px solid var(--glass-border);
            background: var(--glass-bg);
            backdrop-filter: blur(10px);
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            cursor: pointer;
            flex-shrink: 0;
        }

        .ai-uploaded-image:hover {
            transform: scale(1.1);
            border-color: rgba(79, 172, 254, 0.6);
            box-shadow: 0 4px 15px rgba(79, 172, 254, 0.3);
            z-index: 10;
        }

        .ai-uploaded-image img {
            width: 100%;
            height: 100%;
            object-fit: cover;
        }

        .ai-uploaded-image .ai-image-remove {
            position: absolute;
            top: -4px;
            right: -4px;
            width: 16px;
            height: 16px;
            background: #dc3545;
            color: white;
            border: none;
            border-radius: 50%;
            font-size: 0.625rem;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            box-shadow: 0 2px 8px rgba(220, 53, 69, 0.3);
            opacity: 0;
        }

        .ai-uploaded-image:hover .ai-image-remove {
            opacity: 1;
        }

        .ai-uploaded-image .ai-image-remove:hover {
            background: #c82333;
            transform: scale(1.1);
        }

        .ai-uploaded-image .ai-image-info {
            position: absolute;
            bottom: 0;
            left: 0;
            right: 0;
            background: rgba(0, 0, 0, 0.8);
            color: white;
            font-size: 0.5rem;
            padding: 1px 2px;
            text-align: center;
            opacity: 0;
            transition: opacity 0.3s ease;
        }

        .ai-uploaded-image:hover .ai-image-info {
            opacity: 1;
        }



        /* 响应式设计 - AI侧栏优化 */
        @media (max-width: 1200px) {
            .ai-edit-sidebar {
                width: 550px;
                right: -550px;
                min-width: 450px;
            }
        }

        @media (max-width: 992px) {
            .ai-edit-sidebar {
                width: 500px;
                right: -500px;
                min-width: 400px;
            }

            .ai-edit-content {
                padding: var(--spacing-lg);
            }

            .ai-edit-sidebar-header {
                padding: var(--spacing-xs) var(--spacing-md);
            }

            .ai-edit-sidebar-header h4 {
                font-size: 1rem;
            }
        }

        @media (max-width: 768px) {
            .ai-edit-sidebar {
                width: 100%;
                right: -100%;
                min-width: 100%;
                border-radius: 0;
            }

            .ai-edit-sidebar-header {
                border-radius: 0;
                padding: var(--spacing-xs) var(--spacing-sm);
            }

            .ai-edit-content {
                padding: var(--spacing-md);
            }

            .ai-input-buttons {
                flex-direction: column;
                gap: var(--spacing-sm);
            }

            .ai-send-btn {
                width: 100%;
                justify-content: center;
            }

            .ai-clear-context-btn {
                align-self: center;
            }
        }

        @media (max-width: 576px) {
            .ai-edit-sidebar-header h4 {
                font-size: 0.9rem;
            }

            .ai-current-slide-info {
                font-size: 0.6875rem;
                padding: 4px 8px;
            }



            .ai-input-box {
                min-height: 60px;
                font-size: 0.8125rem;
            }

            .ai-send-btn {
                font-size: 0.8125rem;
                padding: var(--spacing-xs) var(--spacing-sm);
            }
        }
    </style>
</head>
<body>
    <div class="editor-container">
        <!-- Header -->
        <div class="editor-header">
            <div class="d-flex justify-content-between align-items-center">
                <div>
                    <h2><i class="fas fa-edit"></i> PPT编辑器</h2>
                    <p class="mb-0">{{ project.title }} - 共 {{ project.slides_data|length if project.slides_data else 0 }} 页</p>
                </div>
                <div>
                    <a href="/dashboard" class="btn btn-outline-light">
                        <i class="fas fa-tasks"></i> 返回主页
                    </a>
                </div>
            </div>
        </div>

        <div class="d-flex">
            <!-- Slides Sidebar -->
            <div class="slides-sidebar" style="flex: 0 0 260px;">
                <div class="p-3">
                    <h6><i class="fas fa-images"></i> 幻灯片</h6>
                </div>
                <div class="slides-container">
                    {% if project.slides_data and project.slides_data|length > 0 %}
                        {% for slide in project.slides_data %}
                        <div class="slide-thumbnail {% if loop.index == 1 %}active{% endif %}"
                             data-slide-index="{{ loop.index0 }}"
                             draggable="true">
                            <div class="drag-indicator top"></div>
                            <div class="slide-preview">
                                <iframe srcdoc="{{ slide.html_content | e }}"
                                        title="Slide {{ loop.index }}"></iframe>
                            </div>
                            <div class="slide-title">{{ loop.index }}. {{ slide.title }}</div>
                            <div class="drag-indicator bottom"></div>
                        </div>
                        {% endfor %}
                    {% else %}
                        <div class="text-center p-4" style="color: #7f8c8d;" id="noSlidesMessage">
                            <div style="font-size: 48px; margin-bottom: 15px;">
                                <i class="fas fa-magic"></i>
                            </div>
                            <h5 style="margin-bottom: 10px;">PPT正在生成中...</h5>
                            <p style="margin-bottom: 15px; font-size: 14px;">
                                幻灯片生成完成后，您可以在这里进行编辑和管理
                            </p>
                            <div class="spinner-border text-primary" role="status" style="margin-bottom: 15px;">
                                <span class="visually-hidden">Loading...</span>
                            </div>
                            <br>
                            <button class="btn btn-primary btn-sm" onclick="checkForUpdates()">
                                <i class="fas fa-refresh"></i> 刷新页面
                            </button>
                        </div>
                    {% endif %}
                </div>
            </div>

            <!-- Main Editor -->
            <div class="main-editor" style="flex: 1;">
                <!-- Toolbar -->
                <div class="editor-toolbar">
                    <div class="btn-group-custom">
                        <button class="mode-toggle active" id="previewMode" onclick="setMode('preview')">
                            <i class="fas fa-eye"></i> 预览
                        </button>
                        <button class="mode-toggle" id="editMode" onclick="setMode('edit')">
                            <i class="fas fa-code"></i> 编辑
                        </button>
                        <button class="mode-toggle" id="splitMode" onclick="setMode('split')">
                            <i class="fas fa-columns"></i> 分屏
                        </button>
                        <button class="mode-toggle" id="quickEditMode" onclick="toggleQuickEditMode()">
                            <i class="fas fa-edit"></i> 修改
                        </button>
                    </div>
                    
                    <div class="btn-group-custom">
                        <button class="btn btn-warning btn-sm" id="slideshowBtn">
                            <i class="fas fa-play"></i> 放映
                        </button>
                        <button class="btn btn-success btn-sm" id="saveSlideBtn">
                            <i class="fas fa-save"></i> 保存
                        </button>
                        <button class="btn btn-primary btn-sm" id="aiEditBtn">
                            <i class="fas fa-robot"></i> AI编辑
                        </button>
                    </div>
                </div>

                <!-- Editor Content -->
                <div class="editor-content">
                    <!-- Preview Pane -->
                    <div class="preview-pane" id="previewPane">
                        {% if project.slides_data and project.slides_data|length > 0 %}
                            <div class="slide-frame-container">
                                <div class="slide-frame-wrapper" id="slideFrameWrapper">
                                    <iframe class="slide-frame" id="slideFrame"
                                            srcdoc="{{ project.slides_data[0].html_content | e }}"
                                            title="Slide Preview"></iframe>
                                    <div class="quick-edit-overlay" id="quickEditOverlay"></div>
                                </div>
                            </div>
                        {% else %}
                            <div class="d-flex align-items-center justify-content-center h-100" style="background: #f8f9fa; border-radius: 8px;">
                                <div class="text-center" style="color: #6c757d;">
                                    <div style="font-size: 64px; margin-bottom: 20px;">
                                        <i class="fas fa-presentation-screen"></i>
                                    </div>
                                    <h4 style="margin-bottom: 15px;">等待PPT生成</h4>
                                    <p style="margin-bottom: 20px;">PPT生成完成后，预览将在这里显示</p>
                                    <button class="btn btn-outline-primary" onclick="window.location.reload()">
                                        <i class="fas fa-refresh"></i> 刷新查看
                                    </button>
                                </div>
                            </div>
                        {% endif %}
                    </div>

                    <!-- Edit Pane -->
                    <div class="edit-pane" id="editPane" style="display: none;">
                        <textarea class="code-editor" id="codeEditor" placeholder="HTML代码将在这里显示...">{{ project.slides_data[0].html_content if project.slides_data and project.slides_data|length > 0 else '' }}</textarea>
                    </div>
                </div>
            </div>
        </div>

        <!-- Export Section -->
        <div class="export-section">
            <div class="btn-group-custom justify-content-center">
                <button class="btn btn-primary" onclick="exportToPDF()">
                    <i class="fas fa-file-pdf"></i> 导出为PDF
                </button>
                <button class="btn btn-warning" onclick="exportToPPTX()">
                    <i class="fas fa-file-powerpoint"></i> 导出为PPTX
                </button>
                <button class="btn btn-success" onclick="downloadHTML()">
                    <i class="fas fa-download"></i> 下载HTML
                </button>
                <button class="btn btn-info" onclick="sharePresentation()">
                    <i class="fas fa-share"></i> 分享演示
                </button>
            </div>
        </div>
    </div>

    <!-- Slideshow Overlay -->
    <div class="slideshow-overlay" id="slideshowOverlay">
        <div class="slideshow-container">
            <div class="slideshow-slide">
                <div class="iframe-container">
                    <iframe id="slideshowFrame1" class="visible" title="Slideshow Frame 1"></iframe>
                    <iframe id="slideshowFrame2" class="hidden" title="Slideshow Frame 2"></iframe>
                </div>
            </div>

            <div class="slideshow-controls">
                <button class="slideshow-btn" onclick="previousSlideshow()">
                    <i class="fas fa-chevron-left"></i> 上一页
                </button>
                <div class="slideshow-info" id="slideshowInfo">1 / 1</div>
                <button class="slideshow-btn" onclick="nextSlideshow()">
                    下一页 <i class="fas fa-chevron-right"></i>
                </button>
            </div>

            <button class="slideshow-exit" onclick="exitSlideshow()">
                <i class="fas fa-times"></i>
            </button>
        </div>
    </div>

    <!-- 右键菜单 -->
    <div class="context-menu" id="contextMenu">
        <div class="context-menu-item" onclick="editSlide()">
            <i class="fas fa-edit"></i>
            <span>编辑幻灯片</span>
        </div>
        <div class="context-menu-item" onclick="copySlide()">
            <i class="fas fa-copy"></i>
            <span>复制幻灯片</span>
        </div>
        <div class="context-menu-item" onclick="pasteSlide()" id="pasteMenuItem">
            <i class="fas fa-paste"></i>
            <span>粘贴幻灯片</span>
        </div>
        <div class="context-menu-item" onclick="insertNewSlide()">
            <i class="fas fa-plus"></i>
            <span>插入新幻灯片</span>
        </div>
        <div class="context-menu-item" onclick="duplicateSlide()">
            <i class="fas fa-clone"></i>
            <span>复制当前页</span>
        </div>
        <div class="context-menu-item" onclick="regenerateContextSlide()">
            <i class="fas fa-sync"></i>
            <span>重新生成</span>
        </div>
        <div class="context-menu-item" onclick="exportSingleSlideHTML()">
            <i class="fas fa-file-code"></i>
            <span>导出为HTML</span>
        </div>
        <div class="context-menu-item" onclick="deleteSlide()">
            <i class="fas fa-trash"></i>
            <span>删除幻灯片</span>
        </div>
    </div>

    <!-- 图片选择菜单 -->
    <div class="image-select-menu" id="imageSelectMenu" style="display: none;">
        <div class="image-select-content">
            <div class="image-select-header">
                <h4><i class="fas fa-image"></i> 选择图片</h4>
                <button class="image-select-close" onclick="closeImageSelectMenu()">
                    <i class="fas fa-times"></i>
                </button>
            </div>
            <div class="image-select-options">
                <button class="image-select-option" onclick="selectFromLocal()">
                    <i class="fas fa-upload"></i>
                    <span>从本地上传</span>
                    <small>选择本地图片文件上传</small>
                </button>
                <button class="image-select-option" onclick="selectFromLibrary()">
                    <i class="fas fa-folder-open"></i>
                    <span>从图床选择</span>
                    <small>从已上传的图片中选择</small>
                </button>
            </div>
        </div>
    </div>

    <!-- 图床选择器 -->
    <div class="image-library-overlay" id="imageLibraryOverlay" style="display: none;">
        <div class="image-library-container">
            <div class="image-library-header">
                <div class="image-library-info">
                    <h4><i class="fas fa-folder-open"></i> 本地图床</h4>
                </div>
                <button class="image-library-close" onclick="closeImageLibrary()">
                    <i class="fas fa-times"></i>
                </button>
            </div>
            <div class="image-library-content">
                <div class="image-library-search">
                    <div class="search-input-group">
                        <i class="fas fa-search"></i>
                        <input type="text" id="imageLibrarySearchInput" placeholder="搜索图片..." />
                        <button class="search-clear-btn" id="imageLibrarySearchClear" style="display: none;" onclick="clearImageLibrarySearch()">
                            <i class="fas fa-times"></i>
                        </button>
                    </div>
                </div>
                <div class="image-library-loading" id="imageLibraryLoading">
                    <i class="fas fa-spinner fa-spin"></i>
                </div>
                <div class="image-library-grid" id="imageLibraryGrid"></div>
                <div class="image-library-pagination" id="imageLibraryPagination" style="display: none;">
                    <div class="pagination-info">
                        <span id="paginationInfo">第 1 页，共 1 页</span>
                    </div>
                    <div class="pagination-controls">
                        <button class="pagination-btn" id="prevPageBtn" onclick="loadPreviousPage()" disabled>
                            <i class="fas fa-chevron-left"></i> 上一页
                        </button>
                        <button class="pagination-btn" id="nextPageBtn" onclick="loadNextPage()" disabled>
                            下一页 <i class="fas fa-chevron-right"></i>
                        </button>
                    </div>
                </div>
                <div class="image-library-empty" id="imageLibraryEmpty" style="display: none;">
                    <i class="fas fa-images"></i>
                </div>
            </div>
            <div class="image-library-actions">
                <button class="image-library-action" onclick="confirmImageSelection()" id="confirmSelectionBtn" disabled>
                    <i class="fas fa-check"></i> 确认选择 (<span id="selectedCount">0</span>)
                </button>
                <button class="image-library-action secondary" onclick="closeImageLibrary()">
                    <i class="fas fa-times"></i> 取消
                </button>
            </div>
        </div>
    </div>

    <!-- 全屏图片预览 -->
    <div class="image-preview-overlay" id="imagePreviewOverlay" style="display: none;">
        <div class="image-preview-container">
            <div class="image-preview-header">
                <div class="image-preview-info">
                    <h4 id="imagePreviewTitle">图片预览</h4>
                    <p id="imagePreviewDetails">加载中...</p>
                </div>
                <button class="image-preview-close" onclick="closeImagePreview()">
                    <i class="fas fa-times"></i>
                </button>
            </div>
            <div class="image-preview-content">
                <img id="imagePreviewImg" src="" alt="图片预览">
                <div class="image-preview-loading" id="imagePreviewLoading">
                    <i class="fas fa-spinner fa-spin"></i>
                    <p>加载中...</p>
                </div>
            </div>
            <div class="image-preview-actions">
                <button class="image-preview-action" onclick="downloadCurrentImage()" title="下载图片">
                    <i class="fas fa-download"></i> 下载
                </button>
                <button class="image-preview-action danger" onclick="removeCurrentImage()" title="删除图片">
                    <i class="fas fa-trash"></i> 删除
                </button>
            </div>
        </div>
    </div>

    <!-- AI编辑侧栏遮罩层 -->
    <div class="ai-sidebar-overlay" id="aiSidebarOverlay" onclick="closeAIEditSidebar()"></div>

    <!-- AI编辑侧栏 -->
    <div class="ai-edit-sidebar" id="aiEditSidebar">
        <div class="ai-sidebar-resize-handle" id="aiSidebarResizeHandle"></div>
        <div class="ai-edit-sidebar-header">
            <h4><i class="fas fa-robot"></i> AI编辑助手</h4>
            <div class="d-flex align-items-center" style="gap: var(--spacing-sm);">
                <div class="ai-current-slide-info" id="aiCurrentSlideInfo">
                    第1页
                </div>
                <div class="ai-header-buttons">
                    <button class="ai-outline-btn" onclick="showSlideOutline()" title="查看当前页大纲">
                        <i class="fas fa-list"></i>
                    </button>
                    <button class="ai-outline-btn" onclick="autoGenerateSlideImages()" title="一键配图">
                        <i class="fas fa-magic"></i>
                    </button>
                    <button class="ai-edit-sidebar-close" onclick="closeAIEditSidebar()">
                        <i class="fas fa-times"></i>
                    </button>
                </div>
            </div>
        </div>

        <div class="ai-edit-content">


            <!-- AI对话区域 -->
            <div class="ai-chat-container">
                <div class="ai-chat-messages" id="aiChatMessages">
                    <div class="ai-message system">
                        <div style="text-align: center; padding: var(--spacing-sm);">
                            <div style="font-size: 2rem; margin-bottom: var(--spacing-sm); color: var(--text-secondary);">
                                <i class="fas fa-magic"></i>
                            </div>
                            <div style="font-weight: 600; margin-bottom: var(--spacing-xs); color: var(--text-primary);">
                                欢迎使用AI编辑助手！
                            </div>
                            <div style="font-size: 0.8125rem; line-height: 1.5; color: var(--text-muted);">
                                您可以告诉我如何修改当前幻灯片，例如：
                                <br>• "修改标题颜色为蓝色"
                                <br>• "添加更多图表"
                                <br>• "调整布局为左右分栏"
                                <br>• "根据上传的图片设计内容"
                                <br>• "将图片居中显示"
                            </div>
                        </div>
                    </div>
                </div>

                <div class="ai-input-container">
                    <textarea
                        class="ai-input-box"
                        id="aiInputBox"
                        placeholder="请输入您的编辑指令..."
                        rows="3"></textarea>


                    <div class="ai-input-buttons">
                        <button class="ai-send-btn" id="aiSendBtn" onclick="sendAIMessage()">
                            <i class="fas fa-paper-plane"></i> 发送
                        </button>
                        <button class="ai-image-upload-btn" id="aiImageUploadBtn" onclick="triggerImageUpload()" title="上传图片">
                            <i class="fas fa-image"></i>
                        </button>
                        <button class="ai-regenerate-btn" onclick="quickRegenerateSlide()" title="重新生成当前幻灯片">
                            <i class="fas fa-sync"></i>
                        </button>
                        <button class="ai-clear-context-btn" onclick="clearAIContext()" title="清除对话上下文">
                            <i class="fas fa-trash"></i>
                        </button>
                    </div>

                    <!-- 隐藏的文件输入 -->
                    <input type="file" id="aiImageFileInput" accept="image/*" multiple style="display: none;">

                    <!-- 上传进度 -->
                    <div class="ai-upload-progress" id="aiUploadProgress" style="display: none;">
                        <div class="ai-progress-bar">
                            <div class="ai-progress-fill" id="aiProgressFill"></div>
                        </div>
                        <div class="ai-progress-text" id="aiProgressText">上传中...</div>
                    </div>

                    <!-- 已上传图片预览 -->
                    <div class="ai-uploaded-images" id="aiUploadedImages"></div>


                </div>
            </div>
        </div>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
    <script>
        let currentSlideIndex = 0;
        let currentMode = 'preview';
        let slidesData = {{ project.slides_data | tojson if project.slides_data and project.slides_data|length > 0 else '[]' }};
        let slideshowIndex = 0;
        let isSlideshow = false;

        // AI编辑相关变量
        let aiChatHistory = {}; // 改为对象，按幻灯片索引存储对话历史
        let isAISending = false;
        let isResizingSidebar = false;
        let sidebarStartWidth = 500;
        let sidebarStartX = 0;

        // 图片上传相关变量
        let uploadedImages = []; // 存储已上传的图片信息
        let isImageUploadExpanded = false;
        let isUploading = false;
        let currentPreviewImage = null; // 当前预览的图片信息
        let selectedLibraryImages = []; // 从图床选择的图片
        let libraryImages = []; // 图床中的所有图片
        let filteredLibraryImages = []; // 搜索过滤后的图片
        let currentSearchTerm = ''; // 当前搜索关键词
        let currentPage = 1; // 当前页码
        let totalPages = 1; // 总页数
        let totalCount = 0; // 总图片数
        let perPage = 1000; // 每页显示数量（设置为大值以获取所有图片）

        // CodeMirror编辑器相关变量
        let codeMirrorEditor = null;
        let isCodeMirrorInitialized = false;

        // 创建安全的data URL
        function createDataUrl(html) {
            try {
                const encoded = btoa(unescape(encodeURIComponent(html)));
                return `data:text/html;charset=utf-8;base64,${encoded}`;
            } catch (error) {
                console.error('Error creating data URL:', error);
                throw error;
            }
        }

        // 优化的iframe内容设置函数，减少卡顿
        function setSafeIframeContent(iframe, html) {
            if (!iframe) {
                console.error('iframe is null or undefined');
                return;
            }

            if (!html) {
                console.error('html content is empty');
                return;
            }

            // 检查内容是否相同，避免不必要的更新
            if (iframe.getAttribute('data-current-content') === html) {
                return;
            }

            // 先清理现有的Chart实例，防止重复渲染
            cleanupIframeCharts(iframe);

            // 使用requestAnimationFrame优化性能
            requestAnimationFrame(() => {
                try {
                    // 直接设置srcdoc，减少延迟
                    iframe.srcdoc = html;
                    iframe.setAttribute('data-current-content', html);

                    // 简化的加载完成处理
                    iframe.onload = function() {
                        // 减少延迟，提高响应速度
                        setTimeout(() => {
                            try {
                                const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
                                const chartElements = iframeDoc.querySelectorAll('canvas[id*="chart"], canvas[id*="Chart"]');

                                if (chartElements.length > 0) {
                                    const iframeWindow = iframe.contentWindow;
                                    if (iframeWindow && iframeWindow.Chart) {
                                        console.log('Chart.js库已加载，图表正常渲染');
                                    }
                                }
                            } catch (e) {
                                // 静默处理错误，避免控制台噪音
                            }
                        }, 50); // 减少延迟时间
                    };
                } catch (e) {
                    console.warn('设置iframe内容失败:', e);
                }
            });
        }

        // 清理iframe中的Chart实例，防止重复渲染
        function cleanupIframeCharts(iframe) {
            if (!iframe) return;

            try {
                const iframeWindow = iframe.contentWindow;
                const iframeDoc = iframe.contentDocument || iframeWindow.document;

                if (!iframeWindow || !iframeDoc) return;

                // 检查是否有Chart.js
                if (iframeWindow.Chart) {
                    console.log('清理现有Chart实例...');

                    // 方法1: 通过Chart.instances清理所有实例
                    if (iframeWindow.Chart.instances) {
                        Object.values(iframeWindow.Chart.instances).forEach(chart => {
                            if (chart && typeof chart.destroy === 'function') {
                                try {
                                    chart.destroy();
                                    console.log('销毁Chart实例');
                                } catch (e) {
                                    console.warn('销毁Chart实例失败:', e);
                                }
                            }
                        });
                    }

                    // 方法2: 通过canvas元素清理
                    const canvasElements = iframeDoc.querySelectorAll('canvas[id*="chart"], canvas[id*="Chart"]');
                    canvasElements.forEach((canvas, index) => {
                        if (canvas.chart) {
                            try {
                                canvas.chart.destroy();
                                console.log(`销毁canvas ${index + 1} 的Chart实例`);
                            } catch (e) {
                                console.warn(`销毁canvas ${index + 1} 的Chart实例失败:`, e);
                            }
                        }
                        // 清理canvas的chart属性
                        delete canvas.chart;
                    });
                }
            } catch (e) {
                console.warn('清理Chart实例时出错:', e);
            }
        }

        // 拖拽和右键菜单相关变量
        let draggedSlideIndex = -1;
        let copiedSlideData = null;
        let contextMenuSlideIndex = -1;

        // 检查是否有幻灯片数据
        let hasSlidesData = slidesData && slidesData.length > 0;

        // 项目状态和生成完成状态
        let projectStatus = '{{ project.status }}';
        let projectOutline = {{ project.outline | tojson if project.outline else 'null' }};

        // 调试信息
        console.log('PPT编辑器调试信息:');
        console.log('- slidesData:', slidesData);
        console.log('- slidesData.length:', slidesData ? slidesData.length : 'undefined');
        console.log('- hasSlidesData:', hasSlidesData);
        console.log('- projectStatus:', projectStatus);
        console.log('- projectOutline:', projectOutline);

        // 检查PPT是否生成完成 - 简化逻辑
        function isPPTGenerationCompleted() {
            // 简单检查：有幻灯片数据就认为生成完成
            return hasSlidesData && slidesData.length > 0;
        }

        // 手动检查更新并刷新页面
        function checkForUpdates() {
            console.log('手动检查项目更新...');
            showNotification('正在检查更新...', 'info');

            // 直接刷新页面以获取最新数据
            setTimeout(() => {
                window.location.reload();
            }, 500);
        }

        // 移除自动检查功能，只保留手动刷新
        // function startAutoCheck() - 已移除定时自动检查逻辑

        // 更新功能按钮状态
        function updateFunctionButtonsState() {
            const isCompleted = isPPTGenerationCompleted();

            // 获取需要控制的按钮和菜单项
            const contextMenu = document.getElementById('contextMenu');
            if (contextMenu) {
                const copyBtn = contextMenu.querySelector('[onclick="copySlide()"]');
                const pasteBtn = contextMenu.querySelector('[onclick="pasteSlide()"]');
                const insertBtn = contextMenu.querySelector('[onclick="insertNewSlide()"]');
                const duplicateBtn = contextMenu.querySelector('[onclick="duplicateSlide()"]');
                const deleteBtn = contextMenu.querySelector('[onclick="deleteSlide()"]');

                // 禁用或启用按钮
                [copyBtn, pasteBtn, insertBtn, duplicateBtn, deleteBtn].forEach(btn => {
                    if (btn) {
                        if (isCompleted) {
                            btn.style.opacity = '1';
                            btn.style.pointerEvents = 'auto';
                            btn.style.color = '';
                        } else {
                            btn.style.opacity = '0.5';
                            btn.style.pointerEvents = 'none';
                            btn.style.color = '#999';
                        }
                    }
                });

                // 添加提示信息
                if (!isCompleted) {
                    [copyBtn, pasteBtn, insertBtn, duplicateBtn, deleteBtn].forEach(btn => {
                        if (btn) {
                            btn.title = 'PPT生成完成后才能使用此功能';
                        }
                    });
                }
            }
        }

        // 缓存缩放比例，避免重复计算
        let cachedScale = null;
        let lastContainerSize = null;

        // 计算并应用iframe缩放，确保内容完全可见
        function applyMainFrameScale() {
            const wrapper = document.getElementById('slideFrameWrapper');
            const iframe = document.getElementById('slideFrame');

            if (!wrapper || !iframe) return;

            // 获取容器的实际尺寸
            const wrapperRect = wrapper.getBoundingClientRect();
            const containerWidth = wrapperRect.width - 20; // 减去内边距
            const containerHeight = wrapperRect.height - 20; // 减去内边距

            // 检查容器尺寸是否变化，如果没有变化则使用缓存的缩放比例
            const currentSize = `${containerWidth}x${containerHeight}`;
            if (lastContainerSize === currentSize && cachedScale !== null) {
                iframe.style.transform = `translate(-50%, -50%) scale(${cachedScale})`;
                return;
            }

            // PPT标准尺寸
            const pptWidth = 1280;
            const pptHeight = 720;

            // 计算缩放比例，确保内容完全可见
            const scaleX = containerWidth / pptWidth;
            const scaleY = containerHeight / pptHeight;
            const scale = Math.min(scaleX, scaleY, 1); // 取较小值，且不超过1

            // 缓存结果
            cachedScale = scale;
            lastContainerSize = currentSize;

            // 应用缩放
            iframe.style.transform = `translate(-50%, -50%) scale(${scale})`;
        }

        // 初始化iframe样式
        function initializeMainFrame() {
            const iframe = document.getElementById('slideFrame');
            if (!iframe) return;

            // 设置固定尺寸和居中定位
            iframe.style.position = 'absolute';
            iframe.style.top = '50%';
            iframe.style.left = '50%';
            iframe.style.width = '1280px';
            iframe.style.height = '720px';
            iframe.style.border = 'none';
            iframe.style.background = 'white';
            iframe.style.borderRadius = '8px';
            iframe.style.transformOrigin = 'center center';

            // 应用缩放
            applyMainFrameScale();
        }

        function selectSlide(index) {
            if (!hasSlidesData) {
                console.log('No slides data available');
                return;
            }

            if (index < 0 || index >= slidesData.length) {
                console.log('Invalid slide index:', index);
                return;
            }

            // 如果选择的是当前幻灯片，直接返回
            if (currentSlideIndex === index) {
                return;
            }

            currentSlideIndex = index;

            // 更新AI编辑助手中的当前页数显示
            updateAICurrentSlideInfo();

            // 切换幻灯片时清除AI对话记录
            clearAIMessagesForSlideSwitch();

            // 切换幻灯片时清除图像选择状态
            clearImageSelection();

            // 使用requestAnimationFrame优化DOM操作
            requestAnimationFrame(() => {
                // Update active thumbnail with animation
                document.querySelectorAll('.slide-thumbnail').forEach((thumb, i) => {
                    if (i === index) {
                        thumb.classList.add('active');
                        // 使用更平滑的滚动
                        thumb.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
                    } else {
                        thumb.classList.remove('active');
                    }
                });

                // Update preview and editor
                if (slidesData[index]) {
                    const slideFrame = document.getElementById('slideFrame');
                    const codeEditor = document.getElementById('codeEditor');

                    if (slideFrame) {
                        // 简化过渡效果，减少卡顿
                        slideFrame.style.opacity = '0.8';
                        slideFrame.style.transition = 'opacity 0.2s ease';

                        try {
                            setSafeIframeContent(slideFrame, slidesData[index].html_content);
                        } catch (error) {
                            console.error('Error setting iframe content:', error);
                        }

                        // 减少延迟时间，提高响应速度
                        setTimeout(() => {
                            slideFrame.style.opacity = '1';
                            // 只在必要时重新应用缩放
                            if (cachedScale === null) {
                                applyMainFrameScale();
                            }
                            // 减少Chart.js重新初始化的频率
                            setTimeout(() => {
                                forceReinitializeIframeJS(slideFrame);

                                // 如果当前是快速编辑模式，重新初始化可编辑元素
                                if (currentMode === 'quickedit' && quickEditMode) {
                                    setTimeout(() => {
                                        initEditableElements();
                                    }, 200);
                                }
                            }, 100);
                        }, 150);
                    }

                    if (codeEditor) {
                        if (codeMirrorEditor && isCodeMirrorInitialized) {
                            codeMirrorEditor.setValue(slidesData[index].html_content);
                        } else {
                            codeEditor.value = slidesData[index].html_content;
                        }
                    }
                }
            });
        }

        // ==================== 快速编辑功能 ====================
        let quickEditMode = false;
        let currentInlineEditor = null;
        let editableElements = [];

        // 切换快速编辑模式
        function toggleQuickEditMode() {
            if (currentMode === 'quickedit') {
                // 如果当前正在编辑，先完成编辑
                if (currentInlineEditor) {
                    finishDirectEdit(true);
                }
                // 退出快速编辑模式
                setMode('preview');
            } else {
                // 进入快速编辑模式
                setMode('quickedit');
            }
        }

        // 启用快速编辑模式
        function enableQuickEdit() {
            quickEditMode = true;
            const previewPane = document.getElementById('previewPane');
            if (previewPane) {
                previewPane.classList.add('quick-edit-mode');
            }

            // 等待iframe加载完成后初始化可编辑元素
            setTimeout(() => {
                initEditableElements();

                // 重新初始化图像选择功能
                const slideFrame = document.getElementById('slideFrame');
                if (slideFrame) {
                    try {
                        const iframeWindow = slideFrame.contentWindow;
                        const iframeDoc = slideFrame.contentDocument || iframeWindow.document;
                        if (iframeWindow && iframeDoc) {
                            initializeImageSelection(slideFrame, iframeWindow, iframeDoc);
                        }
                    } catch (e) {
                        console.error('重新初始化图像选择功能失败:', e);
                    }
                }
            }, 500);

            // console.log('快速编辑模式已启用');
        }

        // 禁用快速编辑模式
        function disableQuickEdit() {
            quickEditMode = false;
            const previewPane = document.getElementById('previewPane');
            if (previewPane) {
                previewPane.classList.remove('quick-edit-mode');
            }

            // 清除所有编辑标识
            clearEditableHighlights();

            // 完成当前的直接编辑
            if (currentInlineEditor) {
                finishDirectEdit(true);
            }

            // 清除图像选择状态
            clearImageSelection();

            // 移除图像选择功能
            const slideFrame = document.getElementById('slideFrame');
            if (slideFrame) {
                try {
                    const iframeDoc = slideFrame.contentDocument || slideFrame.contentWindow.document;
                    if (iframeDoc) {
                        const selectableImages = iframeDoc.querySelectorAll('[data-image-selectable]');
                        selectableImages.forEach(element => {
                            element.removeAttribute('data-image-selectable');
                            element.style.cursor = '';
                            element.classList.remove('image-selected', 'image-selectable');
                            element.style.outline = '';
                            element.style.outlineOffset = '';
                            element.style.boxShadow = '';
                            element.style.transform = '';
                        });
                    }
                } catch (e) {
                    console.error('清理图像选择功能失败:', e);
                }
            }
        }

        // 初始化可编辑元素
        function initEditableElements() {
            const slideFrame = document.getElementById('slideFrame');
            if (!slideFrame || !slideFrame.contentDocument) {
                console.log('iframe未加载完成，稍后重试');
                setTimeout(() => {
                    initEditableElements();
                }, 1000);
                return;
            }

            try {
                const iframeDoc = slideFrame.contentDocument;
                editableElements = [];

                // 查找可编辑的文本元素
                const textSelectors = [
                    'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
                    'p', 'span', 'div',
                    'li', 'td', 'th',
                    '.title', '.subtitle', '.content',
                    '[contenteditable]'
                ];

                textSelectors.forEach(selector => {
                    const elements = iframeDoc.querySelectorAll(selector);
                    elements.forEach(element => {
                        // 检查元素是否包含文本内容且不是容器元素
                        if (element.textContent && element.textContent.trim().length > 0) {
                            // 排除包含其他文本元素的容器
                            const hasTextChildren = Array.from(element.children).some(child =>
                                textSelectors.some(sel => child.matches(sel))
                            );

                            if (!hasTextChildren && !editableElements.includes(element)) {
                                editableElements.push(element);
                                addEditableHighlight(element);
                            }
                        }
                    });
                });

                console.log(`找到 ${editableElements.length} 个可编辑元素`);
            } catch (error) {
                console.error('初始化可编辑元素时出错:', error);
            }
        }

        // 为元素添加编辑高亮
        function addEditableHighlight(element) {
            element.classList.add('quick-edit-highlight');
            element.style.cursor = 'text'; // 改为文本光标

            // 添加点击事件
            element.addEventListener('click', function(e) {
                if (quickEditMode) {
                    e.preventDefault();
                    e.stopPropagation();
                    makeElementDirectlyEditable(element, e);
                }
            });
        }

        // 清除所有编辑高亮
        function clearEditableHighlights() {
            const slideFrame = document.getElementById('slideFrame');
            if (!slideFrame || !slideFrame.contentDocument) return;

            try {
                const iframeDoc = slideFrame.contentDocument;
                const highlightedElements = iframeDoc.querySelectorAll('.quick-edit-highlight');
                highlightedElements.forEach(element => {
                    element.classList.remove('quick-edit-highlight');
                    element.classList.remove('direct-editing');
                    element.style.cursor = 'default';
                    element.contentEditable = false;
                });
            } catch (error) {
                console.error('清除编辑高亮时出错:', error);
            }
        }

        // 使元素直接可编辑
        function makeElementDirectlyEditable(element, clickEvent = null) {
            // 如果已经有元素在编辑中，先完成编辑
            if (currentInlineEditor) {
                finishDirectEdit();
            }

            // 保存原始内容
            const originalText = element.textContent;
            const originalHTML = element.innerHTML;

            // 设置当前编辑元素
            currentInlineEditor = {
                element: element,
                originalText: originalText,
                originalHTML: originalHTML
            };

            // 使元素可编辑
            element.contentEditable = true;
            element.classList.add('direct-editing');

            // 确保iframe内的样式正确应用
            const slideFrame = document.getElementById('slideFrame');
            if (slideFrame && slideFrame.contentDocument) {
                const iframeDoc = slideFrame.contentDocument;

                // 在iframe内添加直接编辑样式
                let styleElement = iframeDoc.getElementById('quick-edit-styles');
                if (!styleElement) {
                    styleElement = iframeDoc.createElement('style');
                    styleElement.id = 'quick-edit-styles';
                    styleElement.textContent = `
                        .direct-editing {
                            outline: 2px solid #4facfe !important;
                            outline-offset: 2px !important;
                            background: rgba(79, 172, 254, 0.1) !important;
                            border-radius: 4px !important;
                            padding: 2px 4px !important;
                            transition: all 0.3s ease !important;
                        }
                        .direct-editing:focus {
                            outline-color: #2980b9 !important;
                            background: rgba(79, 172, 254, 0.15) !important;
                        }
                    `;
                    iframeDoc.head.appendChild(styleElement);
                }
            }

            // 聚焦元素并设置光标位置
            element.focus();

            // 设置光标位置
            try {
                if (clickEvent) {
                    // 如果有点击事件，尝试根据点击位置设置光标
                    const range = element.ownerDocument.createRange();
                    const selection = element.ownerDocument.getSelection();

                    // 使用点击位置设置光标
                    if (element.ownerDocument.caretRangeFromPoint) {
                        const clickRange = element.ownerDocument.caretRangeFromPoint(clickEvent.clientX, clickEvent.clientY);
                        if (clickRange && element.contains(clickRange.startContainer)) {
                            selection.removeAllRanges();
                            selection.addRange(clickRange);
                        } else {
                            // 如果点击位置无效，设置到文本末尾
                            range.selectNodeContents(element);
                            range.collapse(false);
                            selection.removeAllRanges();
                            selection.addRange(range);
                        }
                    } else {
                        // 浏览器不支持caretRangeFromPoint，设置到文本末尾
                        range.selectNodeContents(element);
                        range.collapse(false);
                        selection.removeAllRanges();
                        selection.addRange(range);
                    }
                } else {
                    // 没有点击事件，设置到文本末尾
                    const range = element.ownerDocument.createRange();
                    const selection = element.ownerDocument.getSelection();
                    range.selectNodeContents(element);
                    range.collapse(false);
                    selection.removeAllRanges();
                    selection.addRange(range);
                }
            } catch (error) {
                console.warn('光标设置失败:', error);
                // 如果设置光标失败，至少确保元素获得焦点
                element.focus();
            }

            // 添加键盘事件监听
            element.addEventListener('keydown', handleDirectEditKeydown);
            element.addEventListener('blur', handleDirectEditBlur);
            element.addEventListener('input', handleDirectEditInput);

            console.log('开始直接编辑:', originalText);
        }

        // 处理直接编辑的键盘事件
        function handleDirectEditKeydown(e) {
            if (e.key === 'Enter' && !e.shiftKey) {
                // Enter键完成编辑
                e.preventDefault();
                finishDirectEdit(true);
            } else if (e.key === 'Escape') {
                // ESC键取消编辑
                e.preventDefault();
                finishDirectEdit(false);
            }
        }

        // 处理直接编辑失去焦点
        function handleDirectEditBlur(e) {
            // 延迟处理，避免与其他事件冲突
            setTimeout(() => {
                if (currentInlineEditor && currentInlineEditor.element === e.target) {
                    finishDirectEdit(true);
                }
            }, 100);
        }

        // 处理直接编辑输入事件
        function handleDirectEditInput(e) {
            // 可以在这里添加实时预览更新逻辑
            console.log('内容正在编辑:', e.target.textContent);
        }

        // 完成直接编辑
        function finishDirectEdit(save = true) {
            if (!currentInlineEditor) return;

            const element = currentInlineEditor.element;
            const originalText = currentInlineEditor.originalText;
            const originalHTML = currentInlineEditor.originalHTML;
            const newText = element.textContent;

            // 移除事件监听器
            element.removeEventListener('keydown', handleDirectEditKeydown);
            element.removeEventListener('blur', handleDirectEditBlur);
            element.removeEventListener('input', handleDirectEditInput);

            // 恢复元素状态
            element.contentEditable = false;
            element.classList.remove('direct-editing');
            element.style.outline = '';
            element.style.outlineOffset = '';
            element.style.backgroundColor = '';

            if (save && newText !== originalText) {
                // 保存更改
                saveDirectEdit(element, newText);
                console.log('保存编辑:', originalText, '->', newText);
            } else {
                // 取消更改，恢复原始内容
                element.textContent = originalText;
                console.log('取消编辑，恢复原始内容');
            }

            // 清除当前编辑状态
            currentInlineEditor = null;
        }

        // 保存直接编辑
        function saveDirectEdit(element, newText) {
            if (!element || newText === undefined) return;

            // 获取更新后的HTML内容
            const slideFrame = document.getElementById('slideFrame');
            if (slideFrame && slideFrame.contentDocument) {
                const updatedHtml = slideFrame.contentDocument.documentElement.outerHTML;

                // 更新幻灯片数据
                if (typeof slidesData !== 'undefined' && slidesData[currentSlideIndex]) {
                    slidesData[currentSlideIndex].html_content = updatedHtml;

                    // 更新代码编辑器
                    if (typeof codeMirrorEditor !== 'undefined' && codeMirrorEditor && typeof isCodeMirrorInitialized !== 'undefined' && isCodeMirrorInitialized) {
                        codeMirrorEditor.setValue(updatedHtml);
                    } else {
                        const codeEditor = document.getElementById('codeEditor');
                        if (codeEditor) {
                            codeEditor.value = updatedHtml;
                        }
                    }

                    // 更新缩略图
                    const thumbnailIframe = document.querySelectorAll('.slide-thumbnail .slide-preview iframe')[currentSlideIndex];
                    if (thumbnailIframe && typeof setSafeIframeContent === 'function') {
                        setSafeIframeContent(thumbnailIframe, updatedHtml);
                    }

                    // 保存到服务器
                    if (typeof saveToServer === 'function') {
                        saveToServer();
                    }
                    if (typeof showNotification === 'function') {
                        showNotification('内容已更新并保存！', 'success');
                    }
                }
            }
        }

        function setMode(mode) {
            currentMode = mode;

            // Update button states
            document.querySelectorAll('.mode-toggle').forEach(btn => btn.classList.remove('active'));

            // 处理按钮ID映射
            let buttonId;
            switch(mode) {
                case 'quickedit':
                    buttonId = 'quickEditMode';
                    break;
                default:
                    buttonId = mode + 'Mode';
                    break;
            }

            const modeButton = document.getElementById(buttonId);
            if (modeButton) {
                modeButton.classList.add('active');
            } else {
                console.warn(`Mode button not found: ${buttonId}`);
            }

            const previewPane = document.getElementById('previewPane');
            const editPane = document.getElementById('editPane');

            if (!previewPane || !editPane) {
                console.error('Required panes not found:', { previewPane: !!previewPane, editPane: !!editPane });
                return;
            }

            switch(mode) {
                case 'preview':
                    previewPane.style.display = 'block';
                    previewPane.style.flex = '1';
                    editPane.style.display = 'none';
                    if (typeof disableQuickEdit === 'function') {
                        disableQuickEdit();
                    }
                    break;
                case 'edit':
                    previewPane.style.display = 'none';
                    editPane.style.display = 'block';
                    editPane.style.flex = '1';
                    if (typeof disableQuickEdit === 'function') {
                        disableQuickEdit();
                    }
                    // 延迟重新计算CodeMirror尺寸，确保DOM更新完成
                    setTimeout(() => {
                        if (typeof resizeCodeMirror === 'function') {
                            resizeCodeMirror();
                        }
                    }, 100);
                    break;
                case 'split':
                    previewPane.style.display = 'block';
                    previewPane.style.flex = '1';
                    editPane.style.display = 'block';
                    editPane.style.flex = '1';
                    if (typeof disableQuickEdit === 'function') {
                        disableQuickEdit();
                    }
                    // 延迟重新计算CodeMirror尺寸，确保DOM更新完成
                    setTimeout(() => {
                        if (typeof resizeCodeMirror === 'function') {
                            resizeCodeMirror();
                        }
                    }, 100);
                    break;
                case 'quickedit':
                    previewPane.style.display = 'block';
                    previewPane.style.flex = '1';
                    editPane.style.display = 'none';
                    if (typeof enableQuickEdit === 'function') {
                        enableQuickEdit();
                    }
                    break;
                default:
                    console.warn(`Unknown mode: ${mode}`);
                    break;
            }
        }

        function saveSlide() {
            const codeEditor = document.getElementById('codeEditor');
            let newContent;

            if (codeMirrorEditor && isCodeMirrorInitialized) {
                newContent = codeMirrorEditor.getValue();
            } else {
                newContent = codeEditor.value;
            }

            // Update slides data
            if (slidesData[currentSlideIndex]) {
                slidesData[currentSlideIndex].html_content = newContent;

                // Update preview
                const slideFrame = document.getElementById('slideFrame');
                setSafeIframeContent(slideFrame, newContent);

                // 延迟重新初始化JavaScript以确保内容加载完成
                setTimeout(() => {
                    forceReinitializeIframeJS(slideFrame);
                }, 300);

                // Update thumbnail
                const thumbnailIframe = document.querySelectorAll('.slide-thumbnail .slide-preview iframe')[currentSlideIndex];
                if (thumbnailIframe) {
                    setSafeIframeContent(thumbnailIframe, newContent);
                    // 缩略图不需要重新初始化JavaScript，避免性能问题
                }

                // Save to server
                saveToServer();

                showNotification('幻灯片已保存！', 'success');
            }
        }

        function regenerateSlide() {
            regenerateSlideByIndex(currentSlideIndex);
        }

        // 更新AI编辑助手中的当前页数显示
        function updateAICurrentSlideInfo() {
            const slideInfo = document.getElementById('aiCurrentSlideInfo');
            if (slideInfo && slidesData && slidesData.length > 0) {
                slideInfo.textContent = `第${currentSlideIndex + 1}页 / 共${slidesData.length}页`;
            }

            // 调试信息：记录当前索引状态
            console.log(`🎯 AI助手页数更新: currentSlideIndex=${currentSlideIndex}, 显示为第${currentSlideIndex + 1}页`);
            console.log(`📊 当前幻灯片总数: ${slidesData ? slidesData.length : 'undefined'}`);
            console.log(`🔍 索引验证: 当前索引是否有效=${currentSlideIndex >= 0 && currentSlideIndex < (slidesData ? slidesData.length : 0)}`);
        }

        // 更新AI助手中选中图像的信息显示
        function updateAIAssistantSelectedImage(imageInfo) {
            // 检查是否已存在选中图像信息区域
            let selectedImageContainer = document.getElementById('aiSelectedImageContainer');

            if (!selectedImageContainer) {
                // 创建选中图像信息容器
                selectedImageContainer = document.createElement('div');
                selectedImageContainer.id = 'aiSelectedImageContainer';
                selectedImageContainer.className = 'ai-selected-image-container';

                // 插入到AI输入容器之前
                const inputContainer = document.querySelector('.ai-input-container');
                if (inputContainer) {
                    inputContainer.parentNode.insertBefore(selectedImageContainer, inputContainer);
                }
            }

            if (imageInfo) {
                // 显示选中图像信息
                selectedImageContainer.innerHTML = `
                    <div class="ai-selected-image-header">
                        <h6><i class="fas fa-image"></i> 已选择图像</h6>
                        <button class="ai-clear-selection-btn" onclick="clearImageSelection()" title="清除选择">
                            <i class="fas fa-times"></i>
                        </button>
                    </div>
                    <div class="ai-selected-image-info">
                        <div class="ai-selected-image-preview">
                            <img src="${imageInfo.src}" alt="${imageInfo.alt}" onerror="this.src=''">
                        </div>
                        <div class="ai-selected-image-details">
                            <div class="ai-image-detail-item">
                                <span class="ai-detail-label">类型:</span>
                                <span class="ai-detail-value">${getImageTypeDisplay(imageInfo.type)}</span>
                            </div>
                            <div class="ai-image-detail-item">
                                <span class="ai-detail-label">尺寸:</span>
                                <span class="ai-detail-value">${Math.round(imageInfo.width)} × ${Math.round(imageInfo.height)}</span>
                            </div>
                            <div class="ai-image-detail-item">
                                <span class="ai-detail-label">位置:</span>
                                <span class="ai-detail-value">第${imageInfo.slideIndex + 1}页</span>
                            </div>
                            ${imageInfo.alt ? `
                            <div class="ai-image-detail-item">
                                <span class="ai-detail-label">描述:</span>
                                <span class="ai-detail-value">${imageInfo.alt}</span>
                            </div>
                            ` : ''}
                            ${imageInfo.isBackgroundImage ? `
                            <div class="ai-image-detail-item">
                                <span class="ai-detail-label">背景:</span>
                                <span class="ai-detail-value">CSS背景图像</span>
                            </div>
                            ` : ''}
                        </div>
                    </div>
                    <div class="ai-image-actions">
                        <div class="ai-image-action-row">
                            <button class="ai-regenerate-image-btn" onclick="regenerateSelectedImage()" title="重新生成此图像">
                                <i class="fas fa-sync"></i> 重新生成
                            </button>
                            <button class="ai-replace-image-btn" onclick="replaceSelectedImageFromGallery()" title="从图床选择图片替换">
                                <i class="fas fa-images"></i> 选择替换
                            </button>
                        </div>
                        <div class="ai-image-action-row">
                            <button class="ai-delete-image-btn" onclick="deleteSelectedImage()" title="删除此图像">
                                <i class="fas fa-trash"></i> 删除图像
                            </button>
                        </div>
                    </div>
                `;
                selectedImageContainer.style.display = 'block';
            } else {
                // 隐藏选中图像信息
                selectedImageContainer.style.display = 'none';
            }
        }

        // 清除图像选择
        function clearImageSelection() {
            selectedImageInfo = null;

            // 清除幻灯片中的选择状态
            const slideFrame = document.getElementById('slideFrame');
            if (slideFrame) {
                try {
                    const iframeDoc = slideFrame.contentDocument || slideFrame.contentWindow.document;
                    const selectedImages = iframeDoc.querySelectorAll('.image-selected');
                    selectedImages.forEach(img => {
                        img.classList.remove('image-selected');
                        img.style.outline = '';
                        img.style.outlineOffset = '';
                        img.style.boxShadow = '';
                        img.style.transform = '';
                    });
                } catch (e) {
                    console.error('清除图像选择状态失败:', e);
                }
            }

            // 更新AI助手界面
            updateAIAssistantSelectedImage(null);
        }

        // 重新生成选中的图像
        async function regenerateSelectedImage() {
            if (!selectedImageInfo) {
                showNotification('请先选择要重新生成的图像', 'warning');
                return;
            }

            // 显示确认对话框
            const confirmed = await showImageRegenerateConfirmDialog();
            if (!confirmed) return;

            const regenerateBtn = document.querySelector('.ai-regenerate-image-btn');
            if (!regenerateBtn) return;

            // 保存原始状态用于撤销
            const originalHtmlContent = slidesData[selectedImageInfo.slideIndex].html_content;

            // 禁用按钮并显示加载状态
            const originalText = regenerateBtn.innerHTML;
            regenerateBtn.disabled = true;
            regenerateBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 生成中...';

            // 显示进度提示
            const progressToast = showProgressToast('正在分析图像上下文...');

            try {
                // 更新进度
                updateProgressToast(progressToast, '正在生成新图像...', 30);

                // 构建重新生成请求
                const requestData = {
                    slide_index: selectedImageInfo.slideIndex,
                    image_info: selectedImageInfo,
                    slide_content: {
                        title: selectedImageInfo.slideTitle,
                        html_content: slidesData[selectedImageInfo.slideIndex].html_content
                    },
                    project_topic: '{{ project.topic }}',
                    project_scenario: '{{ project.scenario }}',
                    regeneration_reason: '用户请求重新生成图像'
                };

                // 发送重新生成请求
                const response = await fetch('/api/ai/regenerate-image', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(requestData)
                });

                const result = await response.json();

                if (result.success) {
                    // 更新进度
                    updateProgressToast(progressToast, '正在更新幻灯片...', 80);

                    // 更新幻灯片内容
                    if (result.updated_html_content) {
                        slidesData[selectedImageInfo.slideIndex].html_content = result.updated_html_content;

                        // 更新预览
                        const slideFrame = document.getElementById('slideFrame');
                        if (slideFrame && selectedImageInfo.slideIndex === currentSlideIndex) {
                            setSafeIframeContent(slideFrame, result.updated_html_content);
                            setTimeout(() => {
                                forceReinitializeIframeJS(slideFrame);
                            }, 300);
                        }

                        // 更新缩略图
                        const thumbnailIframe = document.querySelectorAll('.slide-thumbnail .slide-preview iframe')[selectedImageInfo.slideIndex];
                        if (thumbnailIframe) {
                            setSafeIframeContent(thumbnailIframe, result.updated_html_content);
                        }

                        // 保存到服务器
                        updateProgressToast(progressToast, '正在保存...', 90);
                        await saveToServer();

                        // 完成进度
                        updateProgressToast(progressToast, '完成！', 100);

                        // 显示撤销选项
                        showUndoOption(originalHtmlContent, selectedImageInfo.slideIndex);

                        // 清除选择状态
                        clearImageSelection();

                        // 关闭进度提示
                        setTimeout(() => closeProgressToast(progressToast), 1000);

                        showNotification('图像重新生成成功！', 'success');
                    } else {
                        closeProgressToast(progressToast);
                        showNotification('图像生成成功，但更新失败', 'warning');
                    }
                } else {
                    closeProgressToast(progressToast);
                    showNotification(result.message || '图像重新生成失败', 'error');
                }

            } catch (error) {
                console.error('重新生成图像失败:', error);
                closeProgressToast(progressToast);
                showNotification('网络错误，请重试', 'error');
            } finally {
                // 恢复按钮状态
                regenerateBtn.disabled = false;
                regenerateBtn.innerHTML = originalText;
            }
        }

        // 删除选中的图像
        async function deleteSelectedImage() {
            if (!selectedImageInfo) {
                showNotification('请先选择要删除的图像', 'warning');
                return;
            }

            // 显示确认对话框
            const confirmed = await showImageDeleteConfirmDialog();
            if (!confirmed) return;

            try {
                // 保存原始状态用于撤销
                const originalHtmlContent = slidesData[selectedImageInfo.slideIndex].html_content;

                // 从HTML中删除图像
                const updatedHtml = removeImageFromHtml(
                    slidesData[selectedImageInfo.slideIndex].html_content,
                    selectedImageInfo
                );

                if (updatedHtml === slidesData[selectedImageInfo.slideIndex].html_content) {
                    showNotification('未找到要删除的图像', 'warning');
                    return;
                }

                // 更新幻灯片内容
                slidesData[selectedImageInfo.slideIndex].html_content = updatedHtml;

                // 更新预览
                const slideFrame = document.getElementById('slideFrame');
                if (slideFrame && selectedImageInfo.slideIndex === currentSlideIndex) {
                    setSafeIframeContent(slideFrame, updatedHtml);
                    setTimeout(() => {
                        forceReinitializeIframeJS(slideFrame);
                    }, 300);
                }

                // 更新缩略图
                const thumbnailIframe = document.querySelectorAll('.slide-thumbnail .slide-preview iframe')[selectedImageInfo.slideIndex];
                if (thumbnailIframe) {
                    setSafeIframeContent(thumbnailIframe, updatedHtml);
                }

                // 保存到服务器
                await saveToServer();

                // 显示撤销选项
                showUndoOption(originalHtmlContent, selectedImageInfo.slideIndex, '图像删除');

                // 清除选择状态
                clearImageSelection();

                showNotification('图像删除成功！', 'success');

            } catch (error) {
                console.error('删除图像失败:', error);
                showNotification('删除图像失败，请重试', 'error');
            }
        }

        // 从图床选择图片替换选中的图像
        async function replaceSelectedImageFromGallery() {
            if (!selectedImageInfo) {
                showNotification('请先选择要替换的图像', 'warning');
                return;
            }

            try {
                // 显示图片选择对话框
                const selectedImage = await showImageGalleryDialog();
                if (!selectedImage) return;

                // 保存原始状态用于撤销
                const originalHtmlContent = slidesData[selectedImageInfo.slideIndex].html_content;

                // 构建新图像URL
                const newImageUrl = selectedImage.url;

                // 替换HTML中的图像
                const updatedHtml = replaceImageInHtmlClient(
                    slidesData[selectedImageInfo.slideIndex].html_content,
                    selectedImageInfo,
                    newImageUrl
                );

                if (updatedHtml === slidesData[selectedImageInfo.slideIndex].html_content) {
                    showNotification('图像替换失败', 'warning');
                    return;
                }

                // 更新幻灯片内容
                slidesData[selectedImageInfo.slideIndex].html_content = updatedHtml;

                // 更新预览
                const slideFrame = document.getElementById('slideFrame');
                if (slideFrame && selectedImageInfo.slideIndex === currentSlideIndex) {
                    setSafeIframeContent(slideFrame, updatedHtml);
                    setTimeout(() => {
                        forceReinitializeIframeJS(slideFrame);
                    }, 300);
                }

                // 更新缩略图
                const thumbnailIframe = document.querySelectorAll('.slide-thumbnail .slide-preview iframe')[selectedImageInfo.slideIndex];
                if (thumbnailIframe) {
                    setSafeIframeContent(thumbnailIframe, updatedHtml);
                }

                // 保存到服务器
                await saveToServer();

                // 显示撤销选项
                showUndoOption(originalHtmlContent, selectedImageInfo.slideIndex, '图像替换');

                // 清除选择状态
                clearImageSelection();

                showNotification('图像替换成功！', 'success');

            } catch (error) {
                console.error('替换图像失败:', error);
                showNotification('替换图像失败，请重试', 'error');
            }
        }

        // 一键配图功能
        async function autoGenerateSlideImages() {
            if (currentSlideIndex < 0 || currentSlideIndex >= slidesData.length) {
                showNotification('请先选择一个幻灯片', 'warning');
                return;
            }

            const currentSlide = slidesData[currentSlideIndex];
            if (!currentSlide) {
                showNotification('当前幻灯片数据无效', 'error');
                return;
            }

            // 显示确认对话框
            const confirmed = await showAutoImageGenerateConfirmDialog();
            if (!confirmed) return;

            // 显示进度提示
            const progressToast = showProgressToast('正在分析幻灯片内容...');

            try {
                // 更新进度
                updateProgressToast(progressToast, '正在生成配图...', 30);

                // 构建一键配图请求
                const requestData = {
                    slide_index: currentSlideIndex,
                    slide_content: {
                        title: currentSlide.title || `第${currentSlideIndex + 1}页`,
                        html_content: currentSlide.html_content
                    },
                    project_topic: '{{ project.topic }}',
                    project_scenario: '{{ project.scenario }}'
                };

                // 发送一键配图请求
                const response = await fetch('/api/ai/auto-generate-slide-images', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(requestData)
                });

                const result = await response.json();

                if (result.success) {
                    // 更新进度
                    updateProgressToast(progressToast, '正在更新幻灯片...', 80);

                    // 更新幻灯片内容
                    if (result.updated_html_content) {
                        slidesData[currentSlideIndex].html_content = result.updated_html_content;

                        // 更新预览
                        const slideFrame = document.getElementById('slideFrame');
                        if (slideFrame) {
                            setSafeIframeContent(slideFrame, result.updated_html_content);
                            setTimeout(() => {
                                forceReinitializeIframeJS(slideFrame);
                            }, 300);
                        }

                        // 更新缩略图
                        const thumbnailIframe = document.querySelectorAll('.slide-thumbnail .slide-preview iframe')[currentSlideIndex];
                        if (thumbnailIframe) {
                            setSafeIframeContent(thumbnailIframe, result.updated_html_content);
                        }

                        // 更新代码编辑器
                        if (codeMirrorEditor && isCodeMirrorInitialized) {
                            codeMirrorEditor.setValue(result.updated_html_content);
                        } else {
                            const codeEditor = document.getElementById('codeEditor');
                            if (codeEditor) {
                                codeEditor.value = result.updated_html_content;
                            }
                        }

                        // 保存到服务器
                        await saveToServer();

                        // 完成进度
                        updateProgressToast(progressToast, '配图完成！', 100);
                        setTimeout(() => {
                            closeProgressToast(progressToast);
                        }, 1500);

                        // 显示成功消息
                        const imageCount = result.generated_images_count || 0;
                        showNotification(`一键配图完成！已为当前幻灯片生成${imageCount}张图片`, 'success');

                        // 显示AI分析信息
                        if (result.ai_analysis) {
                            addAIMessage('assistant', `配图分析：${result.ai_analysis.reasoning || '已完成图片生成和插入'}`);
                        }

                    } else {
                        closeProgressToast(progressToast);
                        showNotification('配图生成成功，但未能更新幻灯片内容', 'warning');
                    }

                } else {
                    closeProgressToast(progressToast);
                    showNotification(result.message || '一键配图失败，请重试', 'error');
                }

            } catch (error) {
                closeProgressToast(progressToast);
                console.error('一键配图失败:', error);
                showNotification('一键配图失败，请检查网络连接后重试', 'error');
            }
        }

        // 显示一键配图确认对话框
        async function showAutoImageGenerateConfirmDialog() {
            return new Promise((resolve) => {
                const modal = document.createElement('div');
                modal.className = 'modal fade show';
                modal.style.display = 'block';
                modal.style.backgroundColor = 'rgba(0,0,0,0.5)';
                modal.style.zIndex = '20000';
                modal.innerHTML = `
                    <div class="modal-dialog modal-dialog-centered">
                        <div class="modal-content">
                            <div class="modal-header">
                                <h5 class="modal-title">
                                    <i class="fas fa-magic text-primary"></i> 一键配图
                                </h5>
                            </div>
                            <div class="modal-body">
                                <p>AI将自动分析当前幻灯片内容，为其生成合适的配图并插入到适当位置。</p>
                                <div class="alert alert-info">
                                    <i class="fas fa-info-circle"></i>
                                    <strong>功能说明：</strong>
                                    <ul class="mb-0 mt-2">
                                        <li>AI会分析幻灯片的标题和内容</li>
                                        <li>根据内容生成相关的图片描述和关键词</li>
                                        <li>自动生成配图并插入到合适位置</li>
                                        <li>保持原有的布局和样式</li>
                                    </ul>
                                </div>
                            </div>
                            <div class="modal-footer">
                                <button type="button" class="btn btn-secondary" onclick="closeAutoImageConfirmDialog(false)">取消</button>
                                <button type="button" class="btn btn-primary" onclick="closeAutoImageConfirmDialog(true)">
                                    <i class="fas fa-magic"></i> 开始配图
                                </button>
                            </div>
                        </div>
                    </div>
                `;

                document.body.appendChild(modal);

                window.closeAutoImageConfirmDialog = (confirmed) => {
                    document.body.removeChild(modal);
                    delete window.closeAutoImageConfirmDialog;
                    resolve(confirmed);
                };
            });
        }

        // 用户体验优化功能

        // 显示图像重新生成确认对话框
        async function showImageRegenerateConfirmDialog() {
            return new Promise((resolve) => {
                const modal = document.createElement('div');
                modal.className = 'modal fade show';
                modal.style.display = 'block';
                modal.style.backgroundColor = 'rgba(0,0,0,0.5)';
                modal.style.zIndex = '20000'; // 确保在AI助手侧边栏之上
                modal.innerHTML = `
                    <div class="modal-dialog modal-dialog-centered">
                        <div class="modal-content">
                            <div class="modal-header">
                                <h5 class="modal-title">
                                    <i class="fas fa-sync text-primary"></i> 重新生成图像
                                </h5>
                            </div>
                            <div class="modal-body">
                                <p>确定要重新生成选中的图像吗？</p>
                                <div class="alert alert-info">
                                    <i class="fas fa-info-circle"></i>
                                    新图像将保持原有的位置和尺寸，但内容会根据幻灯片上下文重新生成。
                                </div>
                            </div>
                            <div class="modal-footer">
                                <button type="button" class="btn btn-secondary" onclick="closeConfirmDialog(false)">取消</button>
                                <button type="button" class="btn btn-primary" onclick="closeConfirmDialog(true)">
                                    <i class="fas fa-sync"></i> 确定重新生成
                                </button>
                            </div>
                        </div>
                    </div>
                `;

                document.body.appendChild(modal);

                window.closeConfirmDialog = (confirmed) => {
                    document.body.removeChild(modal);
                    delete window.closeConfirmDialog;
                    resolve(confirmed);
                };
            });
        }

        // 显示图像删除确认对话框
        async function showImageDeleteConfirmDialog() {
            return new Promise((resolve) => {
                const modal = document.createElement('div');
                modal.className = 'modal fade show';
                modal.style.display = 'block';
                modal.style.backgroundColor = 'rgba(0,0,0,0.5)';
                modal.style.zIndex = '20000';
                modal.innerHTML = `
                    <div class="modal-dialog modal-dialog-centered">
                        <div class="modal-content">
                            <div class="modal-header">
                                <h5 class="modal-title">
                                    <i class="fas fa-trash text-danger"></i> 删除图像
                                </h5>
                            </div>
                            <div class="modal-body">
                                <p>确定要删除选中的图像吗？</p>
                                <div class="alert alert-warning">
                                    <i class="fas fa-exclamation-triangle"></i>
                                    图像将从幻灯片中完全移除，但可以在5秒内撤销此操作。
                                </div>
                            </div>
                            <div class="modal-footer">
                                <button type="button" class="btn btn-secondary" onclick="closeDeleteDialog(false)">取消</button>
                                <button type="button" class="btn btn-danger" onclick="closeDeleteDialog(true)">
                                    <i class="fas fa-trash"></i> 确定删除
                                </button>
                            </div>
                        </div>
                    </div>
                `;

                document.body.appendChild(modal);

                window.closeDeleteDialog = (confirmed) => {
                    document.body.removeChild(modal);
                    delete window.closeDeleteDialog;
                    resolve(confirmed);
                };
            });
        }

        // 显示图片库选择对话框
        async function showImageGalleryDialog() {
            return new Promise((resolve) => {
                const modal = document.createElement('div');
                modal.className = 'modal fade show';
                modal.style.display = 'block';
                modal.style.backgroundColor = 'rgba(0,0,0,0.5)';
                modal.style.zIndex = '20000';
                modal.innerHTML = `
                    <div class="modal-dialog modal-xl modal-dialog-centered">
                        <div class="modal-content">
                            <div class="modal-header">
                                <h5 class="modal-title">
                                    <i class="fas fa-images text-primary"></i> 选择图片
                                </h5>
                                <button type="button" class="btn-close" onclick="closeGalleryDialog(null)"></button>
                            </div>
                            <div class="modal-body">
                                <!-- 搜索和筛选区域 -->
                                <div class="row mb-3">
                                    <div class="col-md-6">
                                        <div class="input-group">
                                            <span class="input-group-text"><i class="fas fa-search"></i></span>
                                            <input type="text" class="form-control" id="imageSearchInput"
                                                   placeholder="搜索图片标题或描述..." onkeyup="searchImages(event)">
                                        </div>
                                    </div>
                                    <div class="col-md-3">
                                        <select class="form-select" id="imageCategoryFilter" onchange="filterImages()">
                                            <option value="">所有分类</option>
                                            <option value="ai_generated">AI生成</option>
                                            <option value="network_search">网络搜索</option>
                                            <option value="local_upload">本地上传</option>
                                        </select>
                                    </div>
                                    <div class="col-md-3">
                                        <select class="form-select" id="imagePageSize" onchange="changePageSize()">
                                            <option value="12">每页12张</option>
                                            <option value="24" selected>每页24张</option>
                                            <option value="48">每页48张</option>
                                        </select>
                                    </div>
                                </div>

                                <!-- 图片展示区域 -->
                                <div id="imageGalleryContainer" style="min-height: 400px; max-height: 500px; overflow-y: auto;">
                                    <div class="text-center">
                                        <i class="fas fa-spinner fa-spin"></i> 加载图片库...
                                    </div>
                                </div>

                                <!-- 分页区域 -->
                                <div id="imagePagination" class="d-flex justify-content-between align-items-center mt-3">
                                    <div id="imageStats" class="text-muted"></div>
                                    <nav>
                                        <ul class="pagination pagination-sm mb-0" id="paginationList">
                                        </ul>
                                    </nav>
                                </div>
                            </div>
                            <div class="modal-footer">
                                <button type="button" class="btn btn-secondary" onclick="closeGalleryDialog(null)">取消</button>
                                <button type="button" class="btn btn-primary" id="useSelectedBtn" onclick="useSelectedImage()" disabled>
                                    <i class="fas fa-check"></i> 使用选中图片
                                </button>
                            </div>
                        </div>
                    </div>
                `;

                document.body.appendChild(modal);

                // 初始化图片库
                initImageGallery();

                window.closeGalleryDialog = (selectedImage) => {
                    document.body.removeChild(modal);
                    delete window.closeGalleryDialog;
                    delete window.selectGalleryImage;
                    delete window.useSelectedImage;
                    delete window.searchImages;
                    delete window.filterImages;
                    delete window.changePageSize;
                    delete window.goToPage;
                    resolve(selectedImage);
                };

                window.selectGalleryImage = (imageData) => {
                    // 更新选中状态
                    document.querySelectorAll('.gallery-image-item').forEach(item => {
                        item.classList.remove('selected');
                    });
                    event.currentTarget.classList.add('selected');

                    // 启用使用按钮
                    document.getElementById('useSelectedBtn').disabled = false;

                    // 保存选中的图片数据
                    window.selectedImageData = imageData;
                };

                window.useSelectedImage = () => {
                    if (window.selectedImageData) {
                        window.closeGalleryDialog(window.selectedImageData);
                    }
                };
            });
        }

        // 显示进度提示
        function showProgressToast(message) {
            const toast = document.createElement('div');
            toast.className = 'progress-toast';
            toast.innerHTML = `
                <div class="progress-toast-content">
                    <div class="progress-toast-icon">
                        <i class="fas fa-spinner fa-spin"></i>
                    </div>
                    <div class="progress-toast-text">
                        <div class="progress-message">${message}</div>
                        <div class="progress-bar">
                            <div class="progress-fill" style="width: 0%"></div>
                        </div>
                    </div>
                </div>
            `;

            document.body.appendChild(toast);

            // 添加样式
            if (!document.getElementById('progress-toast-styles')) {
                const style = document.createElement('style');
                style.id = 'progress-toast-styles';
                style.textContent = `
                    .progress-toast {
                        position: fixed;
                        top: 20px;
                        right: 20px;
                        background: var(--glass-bg);
                        backdrop-filter: blur(10px);
                        border: 1px solid var(--glass-border);
                        border-radius: var(--border-radius-md);
                        padding: var(--spacing-md);
                        z-index: 25000;
                        min-width: 300px;
                        box-shadow: 0 8px 25px rgba(31, 38, 135, 0.2);
                        animation: slideInRight 0.3s ease;
                    }

                    .progress-toast-content {
                        display: flex;
                        align-items: center;
                        gap: var(--spacing-sm);
                    }

                    .progress-toast-icon {
                        color: var(--primary-color);
                        font-size: 1.2rem;
                    }

                    .progress-toast-text {
                        flex: 1;
                    }

                    .progress-message {
                        font-size: 0.875rem;
                        font-weight: 600;
                        color: var(--text-primary);
                        margin-bottom: var(--spacing-xs);
                    }

                    .progress-bar {
                        height: 4px;
                        background: rgba(0,0,0,0.1);
                        border-radius: 2px;
                        overflow: hidden;
                    }

                    .progress-fill {
                        height: 100%;
                        background: var(--primary-gradient);
                        transition: width 0.3s ease;
                    }

                    @keyframes slideInRight {
                        from { transform: translateX(100%); opacity: 0; }
                        to { transform: translateX(0); opacity: 1; }
                    }
                `;
                document.head.appendChild(style);
            }

            return toast;
        }

        // 更新进度提示
        function updateProgressToast(toast, message, progress) {
            const messageEl = toast.querySelector('.progress-message');
            const fillEl = toast.querySelector('.progress-fill');

            if (messageEl) messageEl.textContent = message;
            if (fillEl) fillEl.style.width = `${progress}%`;
        }

        // 关闭进度提示
        function closeProgressToast(toast) {
            if (toast && toast.parentNode) {
                toast.style.animation = 'slideOutRight 0.3s ease';
                setTimeout(() => {
                    if (toast.parentNode) {
                        toast.parentNode.removeChild(toast);
                    }
                }, 300);
            }
        }

        // 显示撤销选项
        function showUndoOption(originalHtmlContent, slideIndex, operationType = '图像重新生成') {
            const undoToast = document.createElement('div');
            undoToast.className = 'undo-toast';

            const operationMessages = {
                '图像重新生成': { icon: 'fa-sync', message: '图像已重新生成' },
                '图像删除': { icon: 'fa-trash', message: '图像已删除' },
                '图像替换': { icon: 'fa-images', message: '图像已替换' }
            };

            const operation = operationMessages[operationType] || operationMessages['图像重新生成'];

            undoToast.innerHTML = `
                <div class="undo-toast-content">
                    <div class="undo-message">
                        <i class="fas fa-check-circle text-success"></i>
                        ${operation.message}
                    </div>
                    <button class="undo-btn" onclick="undoImageRegeneration('${slideIndex}', this)">
                        <i class="fas fa-undo"></i> 撤销
                    </button>
                </div>
            `;

            // 保存原始内容和操作类型到按钮的数据属性中
            const undoBtn = undoToast.querySelector('.undo-btn');
            undoBtn.setAttribute('data-original-content', originalHtmlContent);
            undoBtn.setAttribute('data-operation-type', operationType);

            document.body.appendChild(undoToast);

            // 添加样式
            if (!document.getElementById('undo-toast-styles')) {
                const style = document.createElement('style');
                style.id = 'undo-toast-styles';
                style.textContent = `
                    .undo-toast {
                        position: fixed;
                        bottom: 20px;
                        right: 20px;
                        background: var(--glass-bg);
                        backdrop-filter: blur(10px);
                        border: 1px solid var(--glass-border);
                        border-radius: var(--border-radius-md);
                        padding: var(--spacing-md);
                        z-index: 25000;
                        box-shadow: 0 8px 25px rgba(31, 38, 135, 0.2);
                        animation: slideInUp 0.3s ease;
                    }

                    .undo-toast-content {
                        display: flex;
                        align-items: center;
                        gap: var(--spacing-md);
                    }

                    .undo-message {
                        font-size: 0.875rem;
                        color: var(--text-primary);
                    }

                    .undo-btn {
                        background: var(--accent-gradient);
                        border: none;
                        color: white;
                        padding: var(--spacing-xs) var(--spacing-sm);
                        border-radius: var(--border-radius-sm);
                        font-size: 0.8125rem;
                        cursor: pointer;
                        transition: all 0.2s ease;
                    }

                    .undo-btn:hover {
                        transform: translateY(-1px);
                        box-shadow: 0 4px 15px rgba(67, 233, 123, 0.3);
                    }

                    @keyframes slideInUp {
                        from { transform: translateY(100%); opacity: 0; }
                        to { transform: translateY(0); opacity: 1; }
                    }
                `;
                document.head.appendChild(style);
            }

            // 15秒后自动隐藏
            setTimeout(() => {
                if (undoToast.parentNode) {
                    undoToast.style.animation = 'slideOutDown 0.3s ease';
                    setTimeout(() => {
                        if (undoToast.parentNode) {
                            undoToast.parentNode.removeChild(undoToast);
                        }
                    }, 300);
                }
            }, 5000);
        }

        // 撤销图像操作（重新生成、删除、替换）
        async function undoImageRegeneration(slideIndex, button) {
            const originalContent = button.getAttribute('data-original-content');
            const operationType = button.getAttribute('data-operation-type') || '图像重新生成';
            if (!originalContent) return;

            try {
                // 恢复原始内容
                slidesData[slideIndex].html_content = originalContent;

                // 更新预览
                if (slideIndex == currentSlideIndex) {
                    const slideFrame = document.getElementById('slideFrame');
                    if (slideFrame) {
                        setSafeIframeContent(slideFrame, originalContent);
                        setTimeout(() => {
                            forceReinitializeIframeJS(slideFrame);
                        }, 300);
                    }
                }

                // 更新缩略图
                const thumbnailIframe = document.querySelectorAll('.slide-thumbnail .slide-preview iframe')[slideIndex];
                if (thumbnailIframe) {
                    setSafeIframeContent(thumbnailIframe, originalContent);
                }

                // 保存到服务器
                await saveToServer();

                // 移除撤销提示
                const undoToast = button.closest('.undo-toast');
                if (undoToast && undoToast.parentNode) {
                    undoToast.parentNode.removeChild(undoToast);
                }

                showNotification(`已撤销${operationType}`, 'info');

            } catch (error) {
                console.error('撤销操作失败:', error);
                showNotification('撤销操作失败', 'error');
            }
        }

        // 从HTML中删除图像（保持完整HTML结构）
        function removeImageFromHtml(htmlContent, imageInfo) {
            try {
                const imageType = imageInfo.type || 'img';
                const oldSrc = imageInfo.src || '';

                let updatedHtml = htmlContent;
                let removed = false;

                if (imageType === 'img') {
                    // 使用正则表达式删除整个img标签
                    const imgRegex = new RegExp(
                        `<img[^>]*src=["'][^"']*${escapeRegExp(oldSrc.split('/').pop())}[^"']*["'][^>]*>`,
                        'gi'
                    );

                    if (imgRegex.test(htmlContent)) {
                        updatedHtml = htmlContent.replace(imgRegex, '');
                        removed = true;
                    } else {
                        // 后备方案：查找包含特定src的img标签
                        const fallbackRegex = new RegExp(
                            `<img[^>]*src=["'][^"']*${escapeRegExp(oldSrc)}[^"']*["'][^>]*>`,
                            'gi'
                        );
                        if (fallbackRegex.test(htmlContent)) {
                            updatedHtml = htmlContent.replace(fallbackRegex, '');
                            removed = true;
                        }
                    }
                } else if (imageType === 'background') {
                    // 删除背景图像样式，但保留元素和其他样式
                    const bgRegex = new RegExp(
                        `(style=["'][^"']*?)background-image:\\s*url\\([^)]*${escapeRegExp(oldSrc.split('/').pop())}[^)]*\\);?([^"']*?["'])`,
                        'gi'
                    );

                    if (bgRegex.test(htmlContent)) {
                        updatedHtml = htmlContent.replace(bgRegex, (match, before, after) => {
                            // 清理可能的多余分号和空格
                            const cleanBefore = before.replace(/;\s*$/, '');
                            const cleanAfter = after.replace(/^\s*;/, '');

                            if (cleanBefore.trim() === 'style="' && cleanAfter.trim() === '"') {
                                // 如果style属性变空，则完全移除
                                return '';
                            } else {
                                return cleanBefore + (cleanBefore.endsWith(';') ? '' : ';') + cleanAfter;
                            }
                        });
                        removed = true;
                    }
                } else if (imageType === 'svg') {
                    // SVG删除相对复杂，这里提供基本支持
                    if (imageInfo.outerHTML) {
                        const svgContent = imageInfo.outerHTML.substring(0, 100); // 取前100字符作为匹配
                        if (htmlContent.includes(svgContent)) {
                            // 尝试找到完整的SVG标签
                            const svgRegex = /<svg[^>]*>[\s\S]*?<\/svg>/gi;
                            const svgMatches = htmlContent.match(svgRegex);

                            if (svgMatches) {
                                for (const svgMatch of svgMatches) {
                                    if (svgMatch.includes(svgContent)) {
                                        updatedHtml = htmlContent.replace(svgMatch, '');
                                        removed = true;
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }

                // 清理可能产生的多余空白
                if (removed) {
                    updatedHtml = updatedHtml.replace(/\s{2,}/g, ' ').trim();
                }

                return removed ? updatedHtml : htmlContent;

            } catch (error) {
                console.error('删除图像失败:', error);
                return htmlContent;
            }
        }

        // 图片库状态管理
        let galleryState = {
            allImages: [],
            filteredImages: [],
            currentPage: 1,
            pageSize: 24,
            searchTerm: '',
            categoryFilter: ''
        };

        // 初始化图片库
        async function initImageGallery() {
            try {
                // 自动分页加载所有图片
                const allImages = await loadAllImages();

                if (allImages.length > 0) {
                    galleryState.allImages = allImages;
                    galleryState.filteredImages = [...allImages];
                    renderImageGallery();
                } else {
                    showEmptyGallery();
                }

            } catch (error) {
                console.error('加载图片库失败:', error);
                showGalleryError(error.message);
            }
        }

        // 加载所有图片（自动分页）
        async function loadAllImages() {
            const allImages = [];
            let currentPage = 1;
            let hasMore = true;

            while (hasMore) {
                try {
                    const response = await fetch(`/api/image/gallery/list?page=${currentPage}&per_page=50`);

                    if (!response.ok) {
                        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
                    }

                    const result = await response.json();

                    if (result.success && result.images && result.images.length > 0) {
                        allImages.push(...result.images);

                        // 检查是否还有更多页面
                        hasMore = result.pagination && result.pagination.has_next;
                        currentPage++;
                    } else {
                        hasMore = false;
                    }
                } catch (error) {
                    console.error(`加载第${currentPage}页图片失败:`, error);
                    hasMore = false;
                }
            }

            return allImages;
        }

        // 渲染图片库
        function renderImageGallery() {
            const container = document.getElementById('imageGalleryContainer');
            if (!container) return;

            const { filteredImages, currentPage, pageSize } = galleryState;

            if (filteredImages.length === 0) {
                showEmptyGallery();
                return;
            }

            // 计算分页
            const totalPages = Math.ceil(filteredImages.length / pageSize);
            const startIndex = (currentPage - 1) * pageSize;
            const endIndex = Math.min(startIndex + pageSize, filteredImages.length);
            const currentImages = filteredImages.slice(startIndex, endIndex);

            // 渲染图片网格
            const imagesHtml = currentImages.map(image => `
                <div class="col-lg-2 col-md-3 col-sm-4 col-6">
                    <div class="gallery-image-item"
                         onclick="selectGalleryImage({
                             id: '${image.id}',
                             url: '${image.url}',
                             title: '${escapeHtml(image.title || '')}',
                             alt: '${escapeHtml(image.alt_text || image.title || '')}',
                             width: ${image.width || 0},
                             height: ${image.height || 0},
                             category: '${image.category || image.source || ''}',
                             description: '${escapeHtml(image.description || '')}'
                         })"
                         ondblclick="handleImageDoubleClick({
                             id: '${image.id}',
                             url: '${image.url}',
                             title: '${escapeHtml(image.title || '')}',
                             alt: '${escapeHtml(image.alt_text || image.title || '')}',
                             width: ${image.width || 0},
                             height: ${image.height || 0},
                             category: '${image.category || image.source || ''}',
                             description: '${escapeHtml(image.description || '')}'
                         })"
                         style="cursor: pointer; border: 2px solid transparent; border-radius: 8px; padding: 8px; transition: all 0.2s ease; position: relative;">
                        <div class="image-wrapper" style="position: relative; overflow: hidden; border-radius: 4px;">
                            <img src="${getImageUrl(image)}" alt="${escapeHtml(image.alt_text || image.title || '')}"
                                 style="width: 100%; height: 120px; object-fit: cover; transition: transform 0.2s ease;"
                                 onload="this.style.opacity='1'; this.parentElement.querySelector('.loading-spinner').style.display='none';"
                                 onerror="handleImageError(this, '${image.id}');">
                            <div class="loading-spinner" style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #ccc;">
                                <i class="fas fa-spinner fa-spin"></i>
                            </div>
                            <div class="image-overlay" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.7); opacity: 0; transition: opacity 0.2s ease; display: flex; align-items: center; justify-content: center;">
                                <i class="fas fa-eye text-white" style="font-size: 1.5rem;"></i>
                            </div>
                        </div>
                        <div class="text-center mt-2">
                            <small class="d-block text-truncate fw-bold">${escapeHtml(image.title || '未命名图片')}</small>
                            <small class="text-muted">${image.width || 0} × ${image.height || 0}</small>
                            ${getImageCategoryBadge(image)}
                        </div>
                    </div>
                </div>
            `).join('');

            container.innerHTML = `
                <div class="row g-3">
                    ${imagesHtml}
                </div>
                <style>
                    .gallery-image-item:hover {
                        border-color: #007bff !important;
                        background-color: rgba(0, 123, 255, 0.1);
                        transform: translateY(-2px);
                        box-shadow: 0 4px 12px rgba(0, 123, 255, 0.2);
                    }
                    .gallery-image-item:hover .image-overlay {
                        opacity: 1;
                    }
                    .gallery-image-item:hover img {
                        transform: scale(1.05);
                    }
                    .gallery-image-item.selected {
                        border-color: #28a745 !important;
                        background-color: rgba(40, 167, 69, 0.1);
                        box-shadow: 0 0 0 3px rgba(40, 167, 69, 0.2);
                    }
                </style>
            `;

            // 更新分页和统计信息
            updatePagination(totalPages);
            updateStats(startIndex + 1, endIndex, filteredImages.length);
        }

        // 更新分页
        function updatePagination(totalPages) {
            const paginationList = document.getElementById('paginationList');
            if (!paginationList) return;

            const { currentPage } = galleryState;
            let paginationHtml = '';

            // 上一页
            paginationHtml += `
                <li class="page-item ${currentPage === 1 ? 'disabled' : ''}">
                    <a class="page-link" href="#" onclick="goToPage(${currentPage - 1}); return false;">
                        <i class="fas fa-chevron-left"></i>
                    </a>
                </li>
            `;

            // 页码
            const maxVisiblePages = 5;
            let startPage = Math.max(1, currentPage - Math.floor(maxVisiblePages / 2));
            let endPage = Math.min(totalPages, startPage + maxVisiblePages - 1);

            if (endPage - startPage < maxVisiblePages - 1) {
                startPage = Math.max(1, endPage - maxVisiblePages + 1);
            }

            for (let i = startPage; i <= endPage; i++) {
                paginationHtml += `
                    <li class="page-item ${i === currentPage ? 'active' : ''}">
                        <a class="page-link" href="#" onclick="goToPage(${i}); return false;">${i}</a>
                    </li>
                `;
            }

            // 下一页
            paginationHtml += `
                <li class="page-item ${currentPage === totalPages ? 'disabled' : ''}">
                    <a class="page-link" href="#" onclick="goToPage(${currentPage + 1}); return false;">
                        <i class="fas fa-chevron-right"></i>
                    </a>
                </li>
            `;

            paginationList.innerHTML = paginationHtml;
        }

        // 更新统计信息
        function updateStats(start, end, total) {
            const statsElement = document.getElementById('imageStats');
            if (statsElement) {
                statsElement.textContent = `显示 ${start}-${end} 项，共 ${total} 张图片`;
            }
        }

        // 初始化CodeMirror编辑器
        function initializeCodeMirror() {
            const textareaElement = document.getElementById('codeEditor');
            if (!textareaElement || isCodeMirrorInitialized) return;

            try {
                // 创建CodeMirror实例
                codeMirrorEditor = CodeMirror.fromTextArea(textareaElement, {
                    mode: 'htmlmixed',
                    theme: 'material',
                    lineNumbers: true,
                    lineWrapping: true,
                    autoCloseTags: true,
                    autoCloseBrackets: true,
                    matchTags: true,
                    foldGutter: true,
                    gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
                    indentUnit: 2,
                    tabSize: 2,
                    indentWithTabs: false,
                    extraKeys: {
                        // 保存功能
                        'Ctrl-S': function(cm) {
                            saveSlide();
                        },
                        'Cmd-S': function(cm) {
                            saveSlide();
                        },
                        // 搜索功能
                        'Ctrl-F': 'findPersistent',
                        'Cmd-F': 'findPersistent',
                        // 查找替换功能
                        'Ctrl-H': 'replace',
                        'Cmd-Alt-F': 'replace',
                        'Ctrl-Shift-H': 'replace',
                        // 查找下一个/上一个
                        'Ctrl-G': 'findNext',
                        'Cmd-G': 'findNext',
                        'Shift-Ctrl-G': 'findPrev',
                        'Shift-Cmd-G': 'findPrev',
                        'F3': 'findNext',
                        'Shift-F3': 'findPrev',
                        // ESC键关闭搜索对话框
                        'Esc': function(cm) {
                            if (cm.state.search && cm.state.search.overlay) {
                                cm.execCommand('clearSearch');
                            }
                        }
                    }
                });

                // 设置编辑器样式 - 使用具体的高度计算
                codeMirrorEditor.setSize('100%', 'auto');

                // 强制刷新编辑器以确保正确的尺寸
                setTimeout(() => {
                    codeMirrorEditor.refresh();
                    // 计算并设置正确的高度
                    const editPane = document.getElementById('editPane');
                    if (editPane) {
                        const rect = editPane.getBoundingClientRect();
                        const height = Math.max(400, rect.height - 40); // 减去padding，最小400px
                        codeMirrorEditor.setSize('100%', height + 'px');
                        console.log('CodeMirror高度设置为:', height + 'px');
                    }
                }, 200);

                // 绑定内容变化事件
                codeMirrorEditor.on('change', function(cm) {
                    clearTimeout(cm.saveTimeout);
                    cm.saveTimeout = setTimeout(() => {
                        if (currentMode === 'split') {
                            // Auto-update preview in split mode
                            const slideFrame = document.getElementById('slideFrame');
                            if (slideFrame && slidesData[currentSlideIndex]) {
                                const newContent = codeMirrorEditor.getValue();
                                slidesData[currentSlideIndex].html_content = newContent;
                                setSafeIframeContent(slideFrame, newContent);
                            }
                        }
                    }, 500);
                });

                isCodeMirrorInitialized = true;
                console.log('CodeMirror编辑器初始化成功，搜索功能已启用');

                // 添加搜索功能的增强配置
                codeMirrorEditor.on('cursorActivity', function(cm) {
                    // 当光标移动时，如果有搜索状态，保持高亮
                    if (cm.state.search && cm.state.search.query) {
                        // 搜索功能已激活，保持高亮状态
                    }
                });

                // 恢复用户的主题偏好
                setTimeout(() => {
                    restoreCodeMirrorTheme();
                }, 100);
            } catch (error) {
                console.error('CodeMirror初始化失败:', error);
                // 如果CodeMirror初始化失败，保持使用原始textarea
            }
        }

        // 切换CodeMirror主题
        function changeCodeMirrorTheme(themeName) {
            if (codeMirrorEditor && isCodeMirrorInitialized) {
                codeMirrorEditor.setOption('theme', themeName);
                console.log('CodeMirror主题已切换为:', themeName);

                // 保存主题偏好到localStorage
                localStorage.setItem('codeMirrorTheme', themeName);

                // 更新下拉菜单显示
                const themeDropdown = document.getElementById('themeDropdown');
                if (themeDropdown) {
                    const themeNames = {
                        'material': 'Material Dark',
                        'monokai': 'Monokai',
                        'dracula': 'Dracula',
                        'default': '默认浅色'
                    };
                    themeDropdown.innerHTML = `<i class="fas fa-palette"></i> ${themeNames[themeName] || themeName}`;
                }
            } else {
                console.warn('CodeMirror编辑器未初始化，无法切换主题');
            }
        }

        // 从localStorage恢复主题偏好
        function restoreCodeMirrorTheme() {
            const savedTheme = localStorage.getItem('codeMirrorTheme');
            if (savedTheme && codeMirrorEditor && isCodeMirrorInitialized) {
                changeCodeMirrorTheme(savedTheme);
            }
        }

        // 重新计算CodeMirror编辑器的尺寸
        function resizeCodeMirror() {
            if (codeMirrorEditor && isCodeMirrorInitialized) {
                const editPane = document.getElementById('editPane');
                if (editPane && editPane.style.display !== 'none') {
                    // 刷新编辑器以重新计算尺寸
                    codeMirrorEditor.refresh();

                    // 设置正确的高度
                    const rect = editPane.getBoundingClientRect();
                    const height = Math.max(400, rect.height - 40); // 减去padding，最小400px
                    if (height > 0) {
                        codeMirrorEditor.setSize('100%', height + 'px');
                        console.log('CodeMirror高度重新设置为:', height + 'px');
                    }
                }
            }
        }



        // 初始化侧栏宽度调整功能
        function initializeSidebarResize() {
            const resizeHandle = document.getElementById('aiSidebarResizeHandle');
            const sidebar = document.getElementById('aiEditSidebar');

            if (!resizeHandle || !sidebar) return;

            resizeHandle.addEventListener('mousedown', (e) => {
                isResizingSidebar = true;
                sidebarStartWidth = sidebar.offsetWidth;
                sidebarStartX = e.clientX;

                document.addEventListener('mousemove', handleSidebarResize);
                document.addEventListener('mouseup', stopSidebarResize);

                e.preventDefault();
            });
        }

        function handleSidebarResize(e) {
            if (!isResizingSidebar) return;

            const sidebar = document.getElementById('aiEditSidebar');
            if (!sidebar) return;

            const deltaX = sidebarStartX - e.clientX; // 向左拖拽为正值
            const newWidth = Math.max(400, Math.min(800, sidebarStartWidth + deltaX));

            sidebar.style.width = newWidth + 'px';
            sidebar.style.right = sidebar.classList.contains('open') ? '0' : `-${newWidth}px`;
        }

        function stopSidebarResize() {
            isResizingSidebar = false;
            document.removeEventListener('mousemove', handleSidebarResize);
            document.removeEventListener('mouseup', stopSidebarResize);
        }

        // AI编辑侧栏控制函数
        function openAIEditSidebar() {
            const sidebar = document.getElementById('aiEditSidebar');
            const overlay = document.getElementById('aiSidebarOverlay');

            sidebar.classList.add('open');
            overlay.classList.add('show');

            // 更新当前页数显示
            updateAICurrentSlideInfo();

            // 聚焦到输入框
            setTimeout(() => {
                document.getElementById('aiInputBox').focus();
            }, 300);
        }

        function closeAIEditSidebar() {
            const sidebar = document.getElementById('aiEditSidebar');
            const overlay = document.getElementById('aiSidebarOverlay');

            sidebar.classList.remove('open');
            overlay.classList.remove('show');
        }

        // 快捷重新生成功能
        function quickRegenerateSlide() {
            if (currentSlideIndex >= 0 && currentSlideIndex < slidesData.length) {
                // 使用与enhanced_ppt_service.py相同的重新生成逻辑
                regenerateSlideByIndex(currentSlideIndex);
                closeAIEditSidebar();
            } else {
                showNotification('请先选择一个幻灯片', 'warning');
            }
        }

        // AI消息处理函数
        function addAIMessage(content, type = 'assistant', messageId = null) {
            const messagesContainer = document.getElementById('aiChatMessages');

            // 如果提供了messageId，尝试找到现有消息并更新
            if (messageId) {
                const existingMessage = document.getElementById(messageId);
                if (existingMessage) {
                    if (type === 'user') {
                        existingMessage.textContent = content;
                    } else {
                        existingMessage.innerHTML = content.replace(/\n/g, '<br>');
                    }
                    messagesContainer.scrollTop = messagesContainer.scrollHeight;
                    return existingMessage;
                }
            }

            // 创建新消息
            const messageDiv = document.createElement('div');
            messageDiv.className = `ai-message ${type}`;
            if (messageId) {
                messageDiv.id = messageId;
            }

            if (type === 'user') {
                messageDiv.textContent = content;
            } else {
                messageDiv.innerHTML = content.replace(/\n/g, '<br>');
            }

            messagesContainer.appendChild(messageDiv);
            messagesContainer.scrollTop = messagesContainer.scrollHeight;

            // 保存到聊天历史（按幻灯片索引存储）
            if (currentSlideIndex >= 0) {
                if (!aiChatHistory[currentSlideIndex]) {
                    aiChatHistory[currentSlideIndex] = [];
                }
                // 将type转换为role格式，以便后端AI能正确理解
                const role = type === 'user' ? 'user' : 'assistant';
                aiChatHistory[currentSlideIndex].push({
                    role: role,
                    content: content,
                    timestamp: Date.now()
                });
            }

            return messageDiv;
        }

        // 添加等待响应动画
        function addWaitingAnimation() {
            const messagesContainer = document.getElementById('aiChatMessages');
            const waitingDiv = document.createElement('div');
            waitingDiv.className = 'ai-message assistant ai-waiting';
            waitingDiv.id = 'ai-waiting-animation';
            waitingDiv.innerHTML = `
                <div class="ai-typing-indicator">
                    <span></span>
                    <span></span>
                    <span></span>
                </div>
                <span style="margin-left: 10px;">AI正在思考中...</span>
            `;

            messagesContainer.appendChild(waitingDiv);
            messagesContainer.scrollTop = messagesContainer.scrollHeight;

            return waitingDiv;
        }

        // 移除等待动画
        function removeWaitingAnimation() {
            const waitingDiv = document.getElementById('ai-waiting-animation');
            if (waitingDiv) {
                waitingDiv.remove();
            }
        }

        function clearAIMessages() {
            const messagesContainer = document.getElementById('aiChatMessages');
            // 保留系统欢迎消息
            const systemMessage = messagesContainer.querySelector('.ai-message.system');
            messagesContainer.innerHTML = '';
            if (systemMessage) {
                messagesContainer.appendChild(systemMessage);
            }
            // 清除当前幻灯片的对话历史
            if (currentSlideIndex >= 0) {
                aiChatHistory[currentSlideIndex] = [];
            }
        }

        // 切换幻灯片时清除对话记录
        function clearAIMessagesForSlideSwitch() {
            const messagesContainer = document.getElementById('aiChatMessages');
            // 保留系统欢迎消息
            const systemMessage = messagesContainer.querySelector('.ai-message.system');
            messagesContainer.innerHTML = '';
            if (systemMessage) {
                messagesContainer.appendChild(systemMessage);
            }
        }

        // 验证当前幻灯片索引的有效性
        function validateCurrentSlideIndex(functionName = 'unknown') {
            const isValid = currentSlideIndex >= 0 && currentSlideIndex < (slidesData ? slidesData.length : 0);

            console.log(`🔍 [${functionName}] 索引验证:`, {
                currentSlideIndex: currentSlideIndex,
                totalSlides: slidesData ? slidesData.length : 'undefined',
                isValid: isValid,
                caller: functionName
            });

            if (!isValid) {
                console.error(`❌ [${functionName}] 无效的幻灯片索引: ${currentSlideIndex}, 总页数: ${slidesData ? slidesData.length : 'undefined'}`);
                return false;
            }

            return true;
        }

        // 清除AI对话上下文
        function clearAIContext() {
            if (confirm('确定要清除当前幻灯片的对话上下文吗？这将删除当前幻灯片的所有对话记录。')) {
                clearAIMessages();
                showNotification('对话上下文已清除', 'info');
            }
        }

        // 显示当前幻灯片大纲
        function showSlideOutline() {
            if (currentSlideIndex < 0 || currentSlideIndex >= slidesData.length) {
                showNotification('请先选择一个幻灯片', 'warning');
                return;
            }

            const currentSlide = slidesData[currentSlideIndex];
            let outlineContent = '';

            // 尝试从项目大纲中获取当前页的信息
            if (projectOutline && projectOutline.slides && projectOutline.slides[currentSlideIndex]) {
                const slideOutline = projectOutline.slides[currentSlideIndex];
                outlineContent = `
                    <h5 style="margin-bottom: 25px; color: #2c3e50; font-size: 1.3em;"><i class="fas fa-file-alt"></i> 第${currentSlideIndex + 1}页大纲编辑</h5>
                    <div style="background: #f8f9fa; padding: 25px; border-radius: 8px; margin: 15px 0;">
                        <div style="margin-bottom: 20px;">
                            <label style="font-weight: bold; display: block; margin-bottom: 8px; color: #495057; font-size: 1.1em;">标题：</label>
                            <input type="text" id="slideTitle" value="${(slideOutline.title || currentSlide.title || '').replace(/"/g, '&quot;')}"
                                   style="width: 100%; padding: 12px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px; box-sizing: border-box;">
                        </div>
                        <div style="margin-bottom: 20px;">
                            <label style="font-weight: bold; display: block; margin-bottom: 8px; color: #495057; font-size: 1.1em;">类型：</label>
                            <select id="slideType" style="width: 100%; padding: 12px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px; box-sizing: border-box;">
                                <option value="title" ${(slideOutline.slide_type || slideOutline.type) === 'title' ? 'selected' : ''}>标题页</option>
                                <option value="content" ${(slideOutline.slide_type || slideOutline.type) === 'content' ? 'selected' : ''}>内容页</option>
                                <option value="conclusion" ${(slideOutline.slide_type || slideOutline.type) === 'conclusion' ? 'selected' : ''}>结论页</option>
                            </select>
                        </div>
                        ${slideOutline.content_points ? `
                            <div style="margin-bottom: 20px;">
                                <label style="font-weight: bold; display: block; margin-bottom: 8px; color: #495057; font-size: 1.1em;">要点：</label>
                                <div id="bulletPointsContainer" style="background: white; border: 1px solid #ddd; border-radius: 6px; padding: 8px; min-height: 120px;">
                                    ${slideOutline.content_points.map((point, index) => `
                                        <div class="bullet-point-item" data-index="${index}" style="display: flex; align-items: flex-start; margin-bottom: 8px; padding: 8px; border-radius: 4px; transition: all 0.2s ease; position: relative;">
                                            <span style="color: #666; margin-right: 8px; font-weight: bold; min-width: 20px;">•</span>
                                            <div style="flex: 1; position: relative;">
                                                <div class="bullet-point-text" contenteditable="true" style="outline: none; min-height: 20px; line-height: 1.4; word-wrap: break-word;">${point}</div>
                                            </div>

                                        </div>
                                    `).join('')}
                                </div>
                                <div style="margin-top: 8px; text-align: right; display: flex; gap: 8px; justify-content: flex-end;">
                                    <button class="enhance-all-btn" onclick="enhanceAllBulletPoints()" title="AI增强所有要点">
                                        🪄 <span>增强要点</span>
                                    </button>
                                    <button onclick="addNewBulletPoint()" style="background: #28a745; color: white; border: none; padding: 8px 16px; border-radius: 6px; cursor: pointer; font-size: 14px; transition: all 0.3s ease; display: flex; align-items: center; gap: 6px;">
                                        <i class="fas fa-plus"></i> <span>添加要点</span>
                                    </button>
                                </div>
                            </div>
                        ` : `
                            <div style="margin-bottom: 20px;">
                                <label style="font-weight: bold; display: block; margin-bottom: 8px; color: #495057; font-size: 1.1em;">要点：</label>
                                <div id="bulletPointsContainer" style="background: white; border: 1px solid #ddd; border-radius: 6px; padding: 8px; min-height: 120px;">
                                    <div class="empty-bullet-points" style="text-align: center; color: #999; padding: 40px 20px;">
                                        <i class="fas fa-list" style="font-size: 24px; margin-bottom: 10px; opacity: 0.5;"></i>
                                        <p style="margin: 0;">暂无要点，点击下方按钮添加</p>
                                    </div>
                                </div>
                                <div style="margin-top: 8px; text-align: right; display: flex; gap: 8px; justify-content: flex-end;">
                                    <button class="enhance-all-btn" onclick="enhanceAllBulletPoints()" title="AI增强所有要点">
                                        🪄 <span>增强所有要点</span>
                                    </button>
                                    <button onclick="addNewBulletPoint()" style="background: #28a745; color: white; border: none; padding: 8px 16px; border-radius: 6px; cursor: pointer; font-size: 14px; transition: all 0.3s ease; display: flex; align-items: center; gap: 6px;">
                                        <i class="fas fa-plus"></i> <span>添加要点</span>
                                    </button>
                                </div>
                            </div>
                        `}
                        <div style="margin-bottom: 15px;">
                            <label style="font-weight: bold; display: block; margin-bottom: 8px; color: #495057; font-size: 1.1em;">描述：</label>
                            <textarea id="slideDescription" rows="4" style="width: 100%; padding: 12px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px; box-sizing: border-box; resize: vertical;">${slideOutline.description || ''}</textarea>
                        </div>
                    </div>
                `;
            } else {
                outlineContent = `
                    <h5 style="margin-bottom: 25px; color: #2c3e50; font-size: 1.3em;"><i class="fas fa-file-alt"></i> 第${currentSlideIndex + 1}页大纲编辑</h5>
                    <div style="background: #f8f9fa; padding: 25px; border-radius: 8px; margin: 15px 0;">
                        <div style="margin-bottom: 20px;">
                            <label style="font-weight: bold; display: block; margin-bottom: 8px; color: #495057; font-size: 1.1em;">标题：</label>
                            <input type="text" id="slideTitle" value="${(currentSlide.title || '').replace(/"/g, '&quot;')}"
                                   style="width: 100%; padding: 12px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px; box-sizing: border-box;">
                        </div>
                        <div style="margin-bottom: 20px;">
                            <label style="font-weight: bold; display: block; margin-bottom: 8px; color: #495057; font-size: 1.1em;">类型：</label>
                            <select id="slideType" style="width: 100%; padding: 12px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px; box-sizing: border-box;">
                                <option value="title">标题页</option>
                                <option value="content" selected>内容页</option>
                                <option value="conclusion">结论页</option>
                            </select>
                        </div>
                        <div style="margin-bottom: 20px;">
                            <label style="font-weight: bold; display: block; margin-bottom: 8px; color: #495057; font-size: 1.1em;">要点：</label>
                            <textarea id="slidePoints" rows="6" placeholder="请输入要点，每行一个..." style="width: 100%; padding: 12px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px; box-sizing: border-box; resize: vertical;"></textarea>
                        </div>
                        <div style="margin-bottom: 15px;">
                            <label style="font-weight: bold; display: block; margin-bottom: 8px; color: #495057; font-size: 1.1em;">描述：</label>
                            <textarea id="slideDescription" rows="4" placeholder="请输入幻灯片描述..." style="width: 100%; padding: 12px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px; box-sizing: border-box; resize: vertical;"></textarea>
                        </div>
                    </div>
                `;
            }

            // 创建大纲编辑模态框
            const modal = document.createElement('div');
            modal.id = 'slideOutlineModal';
            modal.style.cssText = `
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background: rgba(0,0,0,0.5);
                z-index: 10001;
                display: flex;
                justify-content: center;
                align-items: center;
            `;

            const outlineContainer = document.createElement('div');
            outlineContainer.style.cssText = `
                background: white;
                border-radius: 8px;
                padding: 30px;
                width: 90vw;
                max-width: 1200px;
                max-height: 85vh;
                overflow-y: auto;
                position: relative;
                box-shadow: 0 10px 30px rgba(0,0,0,0.3);
            `;

            const closeBtn = document.createElement('button');
            closeBtn.innerHTML = '<i class="fas fa-times"></i>';
            closeBtn.style.cssText = `
                position: absolute;
                top: 15px;
                right: 15px;
                background: #dc3545;
                color: white;
                border: none;
                border-radius: 50%;
                width: 36px;
                height: 36px;
                cursor: pointer;
                font-size: 16px;
                transition: all 0.3s ease;
                z-index: 1;
            `;

            // 添加按钮区域
            const buttonArea = `
                <div style="text-align: right; margin-top: 30px; padding-top: 20px; border-top: 2px solid #e9ecef;">
                    <button onclick="saveSlideOutline()" style="background: #28a745; color: white; border: none; padding: 12px 24px; border-radius: 6px; cursor: pointer; margin-right: 15px; font-size: 16px; font-weight: 500; transition: all 0.3s ease;">
                        <i class="fas fa-save"></i> 保存大纲
                    </button>
                    <button onclick="regenerateFromOutline()" style="background: #007bff; color: white; border: none; padding: 12px 24px; border-radius: 6px; cursor: pointer; font-size: 16px; font-weight: 500; transition: all 0.3s ease;">
                        <i class="fas fa-sync"></i> 根据大纲重新生成
                    </button>
                </div>
            `;

            closeBtn.addEventListener('click', () => {
                document.body.removeChild(modal);
            });

            modal.addEventListener('click', (e) => {
                if (e.target === modal) {
                    document.body.removeChild(modal);
                }
            });

            outlineContainer.innerHTML = outlineContent + buttonArea;
            outlineContainer.appendChild(closeBtn);
            modal.appendChild(outlineContainer);
            document.body.appendChild(modal);
        }

        // 保存幻灯片大纲
        async function saveSlideOutline() {
            const title = document.getElementById('slideTitle').value;
            const type = document.getElementById('slideType').value;
            const description = document.getElementById('slideDescription').value;

            // 从大纲编辑界面收集要点数据
            let points = [];
            const bulletPointsContainer = document.getElementById('bulletPointsContainer');
            if (bulletPointsContainer) {
                const bulletPointItems = bulletPointsContainer.querySelectorAll('.bullet-point-item');
                points = Array.from(bulletPointItems).map(item => {
                    const textElement = item.querySelector('.bullet-point-text');
                    return textElement ? textElement.textContent.trim() : '';
                }).filter(point => point); // 过滤空要点
            } else {
                // 回退到传统的textarea方式（如果没有新的要点容器）
                const pointsElement = document.getElementById('slidePoints');
                points = pointsElement ? pointsElement.value.split('\n').filter(p => p.trim()) : [];
            }

            // 更新本地数据
            if (!projectOutline) {
                projectOutline = { slides: [] };
            }
            if (!projectOutline.slides) {
                projectOutline.slides = [];
            }

            projectOutline.slides[currentSlideIndex] = {
                title: title,
                slide_type: type,
                type: type,
                description: description,
                content_points: points
            };

            // 更新幻灯片标题
            if (slidesData[currentSlideIndex]) {
                slidesData[currentSlideIndex].title = title;
            }

            try {
                // 保存大纲到数据库
                const response = await fetch(`/projects/{{ project.project_id }}/update-outline`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        outline_content: JSON.stringify(projectOutline, null, 2)
                    })
                });

                if (!response.ok) {
                    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
                }

                const data = await response.json();
                if (data.status === 'success') {
                    showNotification('大纲已保存！', 'success');
                } else {
                    throw new Error(data.message || data.error || '保存失败');
                }
            } catch (error) {
                console.error('保存大纲失败:', error);
                showNotification('保存大纲失败：' + error.message, 'error');
                return; // 如果保存失败，不关闭模态框
            }

            // 关闭模态框
            const modal = document.getElementById('slideOutlineModal');
            if (modal) {
                document.body.removeChild(modal);
            }

            // 更新缩略图标题
            const thumbnails = document.querySelectorAll('.slide-thumbnail .slide-title');
            if (thumbnails[currentSlideIndex]) {
                thumbnails[currentSlideIndex].textContent = `${currentSlideIndex + 1}. ${title}`;
            }

            // 更新AI编辑助手右上角的大纲显示
            updateAIOutlineDisplay();
        }

        // 更新AI编辑助手右上角的大纲显示
        function updateAIOutlineDisplay() {
            // 这里可以添加更新右上角大纲显示的逻辑
            // 目前大纲按钮点击时会显示最新的大纲信息
            console.log('大纲已更新，AI编辑时会使用最新大纲');
        }

        // 获取项目选择的全局母版模板
        async function getSelectedGlobalTemplate() {
            try {
                const response = await fetch(`/api/projects/{{ project.project_id }}/selected-global-template`);
                if (!response.ok) {
                    console.warn('获取全局母版失败，将使用默认样式');
                    return null;
                }
                const data = await response.json();
                return data.template || null;
            } catch (error) {
                console.error('获取全局母版模板失败:', error);
                return null;
            }
        }

        // 使用全局母版生成幻灯片HTML内容
        async function generateSlideWithGlobalTemplate(template, title, content) {
            try {
                let htmlTemplate = template.html_template;

                // 替换模板中的占位符
                htmlTemplate = htmlTemplate.replace(/\{\{\s*page_title\s*\}\}/g, title);
                htmlTemplate = htmlTemplate.replace(/\{\{\s*main_heading\s*\}\}/g, title);
                htmlTemplate = htmlTemplate.replace(/\{\{\s*page_content\s*\}\}/g, content);
                htmlTemplate = htmlTemplate.replace(/\{\{\s*current_page_number\s*\}\}/g, '1');
                htmlTemplate = htmlTemplate.replace(/\{\{\s*total_page_count\s*\}\}/g, slidesData.length.toString());

                return htmlTemplate;
            } catch (error) {
                console.error('使用全局母版生成幻灯片失败:', error);
                // 返回默认的HTML内容
                return `
                    <div style="width: 1280px; height: 720px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                                display: flex; flex-direction: column; justify-content: center; align-items: center;
                                color: white; font-family: 'Microsoft YaHei', Arial, sans-serif;">
                        <h1 style="font-size: 48px; margin-bottom: 20px; text-align: center;">${title}</h1>
                        <p style="font-size: 24px; text-align: center;">${content}</p>
                    </div>
                `;
            }
        }

        // 根据大纲重新生成幻灯片
        function regenerateFromOutline() {
            if (confirm('确定要根据当前大纲重新生成这张幻灯片吗？这将覆盖现有内容。')) {
                // 先保存大纲
                saveSlideOutline();

                // 然后重新生成
                setTimeout(() => {
                    regenerateSlideByIndex(currentSlideIndex);
                }, 500);
            }
        }

        // 同步更新大纲（插入、删除幻灯片时调用）
        async function updateOutlineForSlideOperation(operation, slideIndex, slideData = null) {
            try {
                if (!projectOutline) {
                    projectOutline = { slides: [] };
                }
                if (!projectOutline.slides) {
                    projectOutline.slides = [];
                }

                switch (operation) {
                    case 'insert':
                        // 插入新的幻灯片大纲
                        if (slideData) {
                            projectOutline.slides.splice(slideIndex, 0, slideData);
                        }
                        break;
                    case 'delete':
                        // 删除指定位置的幻灯片大纲
                        if (slideIndex >= 0 && slideIndex < projectOutline.slides.length) {
                            projectOutline.slides.splice(slideIndex, 1);
                        }
                        break;
                }

                // 保存更新后的大纲到数据库
                const response = await fetch(`/projects/{{ project.project_id }}/update-outline`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        outline_content: JSON.stringify(projectOutline, null, 2)
                    })
                });

                if (!response.ok) {
                    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
                }

                const data = await response.json();
                if (data.status === 'success') {
                    console.log('大纲已同步更新');
                } else {
                    throw new Error(data.message || data.error || '大纲更新失败');
                }
            } catch (error) {
                console.error('同步更新大纲失败:', error);
                throw error;
            }
        }

        // 发送AI消息 - 使用流式输出
        async function sendAIMessage() {
            const inputBox = document.getElementById('aiInputBox');
            const sendBtn = document.getElementById('aiSendBtn');
            let message = inputBox.value.trim();

            if (!message || isAISending) {
                return;
            }

            // 自动将所有已上传的图片信息嵌入到消息中
            message = autoEmbedUploadedImages(message);

            if (currentSlideIndex < 0 || currentSlideIndex >= slidesData.length) {
                showNotification('请先选择一个幻灯片', 'warning');
                return;
            }

            // 禁用发送按钮和输入框
            isAISending = true;
            sendBtn.disabled = true;
            sendBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 响应中...';
            inputBox.disabled = true;

            // 添加用户消息
            addAIMessage(message, 'user');
            inputBox.value = '';

            // 添加等待动画
            const waitingDiv = addWaitingAnimation();

            try {
                // 构建AI请求上下文
                const currentSlide = slidesData[currentSlideIndex];

                // 获取当前幻灯片的大纲信息
                let slideOutline = null;
                if (projectOutline && projectOutline.slides && projectOutline.slides[currentSlideIndex]) {
                    slideOutline = projectOutline.slides[currentSlideIndex];
                }

                // 获取当前幻灯片的对话历史
                let chatHistory = [];
                if (aiChatHistory[currentSlideIndex]) {
                    chatHistory = aiChatHistory[currentSlideIndex].map(msg => ({
                        role: msg.role,
                        content: msg.content
                    }));
                }

                // 获取所有已上传的图片信息
                const referencedImages = getAllUploadedImages();

                const context = {
                    slideIndex: currentSlideIndex + 1,
                    slideTitle: currentSlide.title,
                    slideContent: currentSlide.html_content,
                    userRequest: message,
                    slideOutline: slideOutline, // 添加当前幻灯片的大纲信息
                    chatHistory: chatHistory, // 添加对话历史
                    images: referencedImages, // 添加图片信息
                    projectInfo: {
                        title: '{{ project.title }}',
                        topic: '{{ project.topic }}',
                        scenario: '{{ project.scenario }}'
                    }
                };

                // 调试信息：显示发送给AI的大纲信息和对话历史
                console.log('发送给AI的大纲信息:', slideOutline);
                console.log('发送给AI的对话历史:', chatHistory);
                console.log('对话历史长度:', chatHistory.length);
                if (slideOutline) {
                    console.log('大纲详情:', {
                        title: slideOutline.title,
                        type: slideOutline.slide_type || slideOutline.type,
                        description: slideOutline.description,
                        points: slideOutline.content_points
                    });
                }

                // 发送流式AI编辑请求
                const response = await fetch('/api/ai/slide-edit/stream', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(context)
                });

                if (!response.ok) {
                    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
                }

                // 处理流式响应
                await handleStreamingResponse(response, waitingDiv);

            } catch (error) {
                console.error('AI编辑请求失败:', error);
                removeWaitingAnimation();
                addAIMessage('抱歉，无法连接到AI服务。请检查网络连接后重试。', 'assistant');
            } finally {
                // 恢复发送按钮和输入框
                isAISending = false;
                sendBtn.disabled = false;
                sendBtn.innerHTML = '<i class="fas fa-paper-plane"></i> 发送';
                inputBox.disabled = false;
                inputBox.focus();
            }
        }

        // 处理流式响应
        async function handleStreamingResponse(response, waitingDiv) {
            const reader = response.body.getReader();
            const decoder = new TextDecoder();
            let buffer = '';
            let aiMessageDiv = null;
            let fullResponse = '';
            let newHtmlContent = null;

            try {
                while (true) {
                    const { done, value } = await reader.read();
                    if (done) break;

                    buffer += decoder.decode(value, { stream: true });
                    const lines = buffer.split('\n');
                    buffer = lines.pop() || '';

                    for (const line of lines) {
                        if (line.trim().startsWith('data: ')) {
                            try {
                                const dataStr = line.slice(6).trim();
                                if (dataStr) {
                                    const data = JSON.parse(dataStr);

                                    if (data.type === 'start') {
                                        // 移除等待动画，开始显示AI回复
                                        removeWaitingAnimation();
                                        // 使用时间戳确保每次对话都有唯一的消息ID
                                        const messageId = 'ai-streaming-message-' + Date.now();
                                        aiMessageDiv = addAIMessage('', 'assistant', messageId);
                                    } else if (data.type === 'content' && data.content) {
                                        // 追加内容到AI消息
                                        fullResponse += data.content;
                                        if (aiMessageDiv) {
                                            // 转义HTML标签，防止实时渲染
                                            const escapedContent = fullResponse
                                                .replace(/&/g, '&amp;')
                                                .replace(/</g, '&lt;')
                                                .replace(/>/g, '&gt;')
                                                .replace(/\n/g, '<br>');
                                            aiMessageDiv.innerHTML = escapedContent;
                                            // 滚动到底部
                                            const messagesContainer = document.getElementById('aiChatMessages');
                                            messagesContainer.scrollTop = messagesContainer.scrollHeight;
                                        }
                                    } else if (data.type === 'complete') {
                                        // 流式输出完成
                                        newHtmlContent = data.newHtmlContent;
                                        fullResponse = data.fullResponse || fullResponse;

                                        // 确保最终内容正确显示，转义HTML标签
                                        if (aiMessageDiv) {
                                            const escapedContent = fullResponse
                                                .replace(/&/g, '&amp;')
                                                .replace(/</g, '&lt;')
                                                .replace(/>/g, '&gt;')
                                                .replace(/\n/g, '<br>');
                                            aiMessageDiv.innerHTML = escapedContent;
                                        }

                                        // 如果有HTML内容，添加应用按钮
                                        if (newHtmlContent) {
                                            addApplyChangesButton(aiMessageDiv, newHtmlContent);
                                        }

                                        break;
                                    } else if (data.type === 'error') {
                                        removeWaitingAnimation();
                                        addAIMessage('抱歉，处理您的请求时出现了错误：' + (data.error || '未知错误'), 'assistant');
                                        break;
                                    }
                                }
                            } catch (e) {
                                console.error('解析流式数据失败:', e);
                            }
                        }
                    }
                }
            } catch (error) {
                console.error('处理流式响应失败:', error);
                removeWaitingAnimation();
                addAIMessage('抱歉，处理流式响应时出现了错误。', 'assistant');
            }
        }

        // 添加应用更改按钮
        function addApplyChangesButton(messageDiv, newHtmlContent) {
            if (!messageDiv || !newHtmlContent) return;

            // 检查是否已经有按钮了
            if (messageDiv.querySelector('.ai-apply-changes-btn')) return;

            const buttonContainer = document.createElement('div');
            buttonContainer.className = 'ai-apply-changes-container';
            buttonContainer.style.cssText = `
                margin-top: 15px;
                padding-top: 15px;
                border-top: 1px solid #eee;
                display: flex;
                gap: 10px;
                align-items: center;
            `;

            const applyBtn = document.createElement('button');
            applyBtn.className = 'ai-apply-changes-btn';
            applyBtn.innerHTML = '<i class="fas fa-check"></i> 应用更改';
            applyBtn.style.cssText = `
                background: #28a745;
                color: white;
                border: none;
                padding: 8px 16px;
                border-radius: 4px;
                cursor: pointer;
                font-size: 14px;
                transition: background-color 0.2s ease;
            `;

            const previewBtn = document.createElement('button');
            previewBtn.className = 'ai-preview-changes-btn';
            previewBtn.innerHTML = '<i class="fas fa-eye"></i> 预览';
            previewBtn.style.cssText = `
                background: #007bff;
                color: white;
                border: none;
                padding: 8px 16px;
                border-radius: 4px;
                cursor: pointer;
                font-size: 14px;
                transition: background-color 0.2s ease;
            `;

            // 绑定事件
            applyBtn.addEventListener('click', async () => {
                applyBtn.disabled = true;
                applyBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> 应用中...';
                try {
                    await applyAIChanges(newHtmlContent);
                    applyBtn.innerHTML = '<i class="fas fa-check"></i> 已保存';
                    applyBtn.style.background = '#28a745';
                    applyBtn.style.color = 'white';

                    // 3秒后变为已应用状态
                    setTimeout(() => {
                        applyBtn.innerHTML = '<i class="fas fa-check-circle"></i> 已应用';
                        applyBtn.style.background = '#6c757d';
                    }, 3000);
                } catch (error) {
                    console.error('Apply changes error:', error);
                    applyBtn.innerHTML = '<i class="fas fa-exclamation-triangle"></i> 保存失败';
                    applyBtn.style.background = '#dc3545';
                    applyBtn.style.color = 'white';

                    // 显示详细错误信息
                    const errorMsg = error.message || '未知错误';
                    applyBtn.title = `保存失败: ${errorMsg}`;

                    setTimeout(() => {
                        applyBtn.innerHTML = '<i class="fas fa-check"></i> 重试应用';
                        applyBtn.style.background = '#28a745';
                        applyBtn.style.color = 'white';
                        applyBtn.title = '';
                        applyBtn.disabled = false;
                    }, 3000);
                }
            });

            previewBtn.addEventListener('click', () => {
                showHTMLPreview(newHtmlContent);
            });

            // 悬停效果
            applyBtn.addEventListener('mouseenter', () => {
                if (!applyBtn.disabled) applyBtn.style.background = '#218838';
            });
            applyBtn.addEventListener('mouseleave', () => {
                if (!applyBtn.disabled) applyBtn.style.background = '#28a745';
            });

            previewBtn.addEventListener('mouseenter', () => {
                previewBtn.style.background = '#0056b3';
            });
            previewBtn.addEventListener('mouseleave', () => {
                previewBtn.style.background = '#007bff';
            });

            buttonContainer.appendChild(applyBtn);
            buttonContainer.appendChild(previewBtn);
            messageDiv.appendChild(buttonContainer);
        }

        // 显示HTML预览
        function showHTMLPreview(htmlContent) {
            // 创建全屏预览模态框
            const modal = document.createElement('div');
            modal.style.cssText = `
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background: black;
                z-index: 10000;
                display: flex;
                justify-content: center;
                align-items: center;
                padding: 20px;
                box-sizing: border-box;
            `;

            const closeBtn = document.createElement('button');
            closeBtn.innerHTML = '<i class="fas fa-times"></i>';
            closeBtn.style.cssText = `
                position: absolute;
                top: 20px;
                right: 20px;
                background: rgba(255,255,255,0.2);
                color: white;
                border: 2px solid rgba(255,255,255,0.3);
                border-radius: 50%;
                width: 40px;
                height: 40px;
                cursor: pointer;
                font-size: 16px;
                z-index: 10001;
                transition: all 0.3s ease;
            `;

            closeBtn.addEventListener('mouseenter', () => {
                closeBtn.style.background = 'rgba(255,255,255,0.3)';
                closeBtn.style.borderColor = 'rgba(255,255,255,0.5)';
            });

            closeBtn.addEventListener('mouseleave', () => {
                closeBtn.style.background = 'rgba(255,255,255,0.2)';
                closeBtn.style.borderColor = 'rgba(255,255,255,0.3)';
            });

            // 创建PPT容器，使用与全屏放映相同的样式
            const slideContainer = document.createElement('div');
            slideContainer.style.cssText = `
                background: white;
                border-radius: 10px;
                box-shadow: 0 10px 30px rgba(255,255,255,0.2);
                overflow: hidden;
                position: relative;
                width: 100%;
                height: 100%;
                max-width: calc(100vh * 16/9 - 40px);
                max-height: calc(100vw * 9/16 - 40px);
                aspect-ratio: 16/9;
            `;

            const iframe = document.createElement('iframe');
            iframe.style.cssText = `
                width: 100%;
                height: 100%;
                border: none;
                background: white;
            `;
            iframe.srcdoc = htmlContent;

            closeBtn.addEventListener('click', () => {
                document.body.removeChild(modal);
            });

            modal.addEventListener('click', (e) => {
                if (e.target === modal) {
                    document.body.removeChild(modal);
                }
            });

            // 键盘事件支持
            const handleKeyPress = (e) => {
                if (e.key === 'Escape') {
                    document.body.removeChild(modal);
                    document.removeEventListener('keydown', handleKeyPress);
                }
            };
            document.addEventListener('keydown', handleKeyPress);

            slideContainer.appendChild(iframe);
            modal.appendChild(closeBtn);
            modal.appendChild(slideContainer);
            document.body.appendChild(modal);
        }

        // 应用AI更改
        async function applyAIChanges(newHtmlContent) {
            try {
                // 验证当前索引状态
                if (!validateCurrentSlideIndex('applyAIChanges')) {
                    throw new Error(`无效的幻灯片索引: ${currentSlideIndex}，总页数: ${slidesData ? slidesData.length : 'undefined'}`);
                }

                // 获取当前正在编辑的幻灯片索引，确保索引正确
                const targetSlideIndex = currentSlideIndex;

                console.log(`🎯 应用AI更改到第${targetSlideIndex + 1}页 (索引: ${targetSlideIndex})`);
                console.log(`📊 当前幻灯片总数: ${slidesData.length}`);

                // 双重验证索引有效性
                if (targetSlideIndex < 0 || targetSlideIndex >= slidesData.length) {
                    throw new Error(`无效的幻灯片索引: ${targetSlideIndex}，总页数: ${slidesData.length}`);
                }

                // 更新当前幻灯片数据
                slidesData[targetSlideIndex].html_content = newHtmlContent;

                // 标记当前幻灯片为用户编辑状态
                slidesData[targetSlideIndex].is_user_edited = true;

                // 更新预览
                const slideFrame = document.getElementById('slideFrame');
                if (slideFrame) {
                    setSafeIframeContent(slideFrame, newHtmlContent);
                    setTimeout(() => {
                        forceReinitializeIframeJS(slideFrame);
                    }, 300);
                }

                // 更新缩略图
                const thumbnailIframe = document.querySelectorAll('.slide-thumbnail .slide-preview iframe')[targetSlideIndex];
                if (thumbnailIframe) {
                    setSafeIframeContent(thumbnailIframe, newHtmlContent);
                }

                // 更新代码编辑器
                const codeEditor = document.getElementById('codeEditor');
                if (codeEditor) {
                    if (codeMirrorEditor && isCodeMirrorInitialized) {
                        codeMirrorEditor.setValue(newHtmlContent);
                    } else {
                        codeEditor.value = newHtmlContent;
                    }
                }

                // 保存到服务器 - 使用单个幻灯片保存API，确保使用正确的索引
                console.log(`💾 开始保存第${targetSlideIndex + 1}页到服务器...`);
                const saveSuccess = await saveSingleSlideToServer(targetSlideIndex, newHtmlContent);

                if (saveSuccess) {
                    showNotification(`AI更改已应用并保存！(第${targetSlideIndex + 1}页)`, 'success');
                } else {
                    showNotification(`AI更改已应用，但保存第${targetSlideIndex + 1}页时出现问题`, 'warning');
                }

            } catch (error) {
                console.error('应用AI更改失败:', error);

                // 尝试恢复原始内容
                try {
                    // 这里可以添加恢复逻辑，但需要保存原始内容
                    console.log('Error occurred, but changes have been applied locally');
                } catch (restoreError) {
                    console.error('Failed to restore original content:', restoreError);
                }

                showNotification('应用更改失败：' + error.message, 'error');
                throw error; // 重新抛出错误以便按钮状态处理
            }
        }

        function regenerateContextSlide() {
            hideContextMenu();
            regenerateSlideByIndex(contextMenuSlideIndex);
        }

        function regenerateSlideByIndex(slideIndex) {
            if (slideIndex < 0 || slideIndex >= slidesData.length) {
                alert('无效的幻灯片索引');
                return;
            }

            const slideTitle = slidesData[slideIndex].title || `第${slideIndex + 1}页`;
            if (confirm(`确定要重新生成"${slideTitle}"吗？这将覆盖现有内容。`)) {
                // Show loading indicator
                const loadingDiv = document.createElement('div');
                loadingDiv.id = 'regenerateLoading';
                loadingDiv.style.cssText = `
                    position: fixed;
                    top: 50%;
                    left: 50%;
                    transform: translate(-50%, -50%);
                    background: rgba(0,0,0,0.8);
                    color: white;
                    padding: 20px;
                    border-radius: 10px;
                    z-index: 9999;
                    text-align: center;
                `;
                loadingDiv.innerHTML = `
                    <i class="fas fa-spinner fa-spin"></i>
                    <div style="margin-top: 10px;">正在重新生成幻灯片...</div>
                `;
                document.body.appendChild(loadingDiv);

                // Call API to regenerate slide
                fetch(`/api/projects/{{ project.project_id }}/slides/${slideIndex + 1}/regenerate`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        scenario: '{{ project.scenario }}',
                        topic: '{{ project.topic }}',
                        requirements: '{{ project.requirements or "" }}',
                        language: 'zh'
                    })
                })
                .then(response => response.json())
                .then(data => {
                    document.body.removeChild(loadingDiv);
                    if (data.success) {
                        // 更新本地数据而不是刷新页面
                        if (data.slide_data) {
                            // 更新slidesData中的对应幻灯片
                            slidesData[slideIndex] = data.slide_data;

                            // 更新缩略图显示
                            updateThumbnailDisplay(slideIndex, data.slide_data);

                            // 如果当前正在查看这个幻灯片，更新主预览区域
                            if (currentSlideIndex === slideIndex) {
                                updateMainPreview(data.slide_data);
                                updateCodeEditor(data.slide_data);
                            }

                            showNotification('幻灯片重新生成成功！', 'success');
                        } else {
                            // 如果没有返回slide_data，则刷新页面
                            showNotification('幻灯片重新生成成功！正在刷新页面...', 'success');
                            setTimeout(() => location.reload(), 1000);
                        }
                    } else {
                        showNotification('重新生成失败：' + (data.error || '未知错误'), 'error');
                    }
                })
                .catch(error => {
                    document.body.removeChild(loadingDiv);
                    alert('重新生成失败：' + error.message);
                });
            }
        }

        // 更新缩略图显示
        function updateThumbnailDisplay(slideIndex, slideData) {
            const thumbnails = document.querySelectorAll('.slide-thumbnail');
            if (thumbnails[slideIndex]) {
                const thumbnail = thumbnails[slideIndex];

                // 更新缩略图中的iframe内容
                const iframe = thumbnail.querySelector('iframe');
                if (iframe && slideData.html_content) {
                    setSafeIframeContent(iframe, slideData.html_content);
                }

                // 更新标题
                const titleElement = thumbnail.querySelector('.slide-title');
                if (titleElement && slideData.title) {
                    titleElement.textContent = `${slideIndex + 1}. ${slideData.title}`;
                }
            }
        }

        // 更新主预览区域
        function updateMainPreview(slideData) {
            const slideFrame = document.getElementById('slideFrame');
            if (slideFrame && slideData.html_content) {
                setSafeIframeContent(slideFrame, slideData.html_content);
            }
        }

        // 更新代码编辑器
        function updateCodeEditor(slideData) {
            if (slideData.html_content) {
                if (codeMirrorEditor) {
                    // 如果使用CodeMirror
                    codeMirrorEditor.setValue(slideData.html_content);
                } else {
                    // 如果使用普通textarea
                    const codeEditor = document.getElementById('codeEditor');
                    if (codeEditor) {
                        codeEditor.value = slideData.html_content;
                    }
                }
            }
        }

        async function saveToServer() {
            try {
                console.log('🔄 开始批量保存幻灯片到服务器...', slidesData.length, '页');

                // 标记所有幻灯片为用户编辑状态
                slidesData.forEach(slide => {
                    slide.is_user_edited = true;
                });

                // 使用批量保存API
                const response = await fetch(`/api/projects/{{ project.project_id }}/slides/batch-save`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        slides_data: slidesData
                    })
                });

                if (!response.ok) {
                    const errorText = await response.text();
                    console.error(`❌ 批量保存请求失败:`, errorText);
                    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
                }

                const data = await response.json();
                console.log(`✅ 批量保存响应:`, data);

                if (data.success) {
                    console.log(`✅ 批量保存成功: ${data.slides_count} 张幻灯片`);
                    return true;
                } else {
                    console.error(`❌ 批量保存失败:`, data.error);
                    throw new Error(data.error || 'Unknown batch save error');
                }

            } catch (error) {
                console.error('❌ 批量保存幻灯片时发生错误:', error);
                // 如果批量保存失败，回退到逐个保存
                console.log('🔄 回退到逐个保存模式...');
                return await saveToServerFallback();
            }
        }

        // 回退保存方法 - 逐个保存
        async function saveToServerFallback() {
            try {
                console.log('🔄 开始逐个保存幻灯片到服务器...', slidesData.length, '页');

                let saveSuccessCount = 0;
                let saveFailureCount = 0;
                const saveErrors = [];

                for (let i = 0; i < slidesData.length; i++) {
                    try {
                        const slide = slidesData[i];

                        // 标记为用户编辑状态
                        slide.is_user_edited = true;

                        console.log(`💾 保存第${i + 1}页: ${slide.title}`);

                        const success = await saveSingleSlideToServer(i, slide.html_content);
                        if (success) {
                            saveSuccessCount++;
                            console.log(`✅ 第${i + 1}页保存成功`);
                        } else {
                            saveFailureCount++;
                            saveErrors.push(`第${i + 1}页保存失败`);
                            console.error(`❌ 第${i + 1}页保存失败`);
                        }
                    } catch (error) {
                        saveFailureCount++;
                        const errorMsg = `第${i + 1}页保存异常: ${error.message}`;
                        saveErrors.push(errorMsg);
                        console.error(`❌ ${errorMsg}`);
                    }
                }

                console.log(`📊 逐个保存结果: 成功${saveSuccessCount}页, 失败${saveFailureCount}页`);

                if (saveFailureCount > 0) {
                    console.warn('⚠️ 部分幻灯片保存失败:', saveErrors);
                    // 即使部分失败，也不抛出错误，让用户知道部分保存成功
                    return saveSuccessCount > 0; // 只要有成功的就返回true
                } else {
                    console.log('✅ 所有幻灯片保存成功');
                    return true;
                }

            } catch (error) {
                console.error('❌ 逐个保存幻灯片时发生错误:', error);
                throw error; // 重新抛出错误以便调用者处理
            }
        }

        // 清理数据库中多余的幻灯片
        async function cleanupExcessSlides() {
            try {
                console.log(`🧹 开始清理多余的幻灯片，当前幻灯片数量: ${slidesData.length}`);

                const response = await fetch(`/api/projects/{{ project.project_id }}/slides/cleanup`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        current_slide_count: slidesData.length
                    })
                });

                if (!response.ok) {
                    const errorText = await response.text();
                    console.error(`❌ 清理请求失败:`, errorText);
                    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
                }

                const data = await response.json();
                console.log(`✅ 清理响应:`, data);

                if (data.success) {
                    console.log(`✅ 成功清理了 ${data.deleted_count} 张多余的幻灯片`);
                    return true;
                } else {
                    console.error(`❌ 清理失败:`, data.error);
                    throw new Error(data.error || 'Unknown cleanup error');
                }

            } catch (error) {
                console.error('❌ 清理多余幻灯片时发生错误:', error);
                // 不抛出错误，因为这不应该阻止删除操作的完成
                return false;
            }
        }

        // 保存单个幻灯片到服务器
        async function saveSingleSlideToServer(slideIndex, htmlContent) {
            try {
                // 验证输入参数
                if (typeof slideIndex !== 'number' || slideIndex < 0) {
                    throw new Error(`无效的幻灯片索引: ${slideIndex}`);
                }

                if (!htmlContent || typeof htmlContent !== 'string') {
                    throw new Error('HTML内容不能为空');
                }

                // 验证索引范围
                if (slideIndex >= slidesData.length) {
                    throw new Error(`幻灯片索引超出范围: ${slideIndex}，总页数: ${slidesData.length}`);
                }

                console.log(`🔄 开始保存第${slideIndex + 1}页...`);
                console.log(`📄 HTML内容长度: ${htmlContent.length} 字符`);
                console.log(`📊 当前幻灯片索引: ${slideIndex}，总页数: ${slidesData.length}`);
                console.log(`🎯 API路径: /api/projects/{{ project.project_id }}/slides/${slideIndex}/save`);

                const requestData = {
                    html_content: htmlContent
                };

                console.log(`📤 发送保存请求:`, {
                    slideIndex: slideIndex,
                    contentLength: htmlContent.length,
                    apiPath: `/api/projects/{{ project.project_id }}/slides/${slideIndex}/save`
                });

                const response = await fetch(`/api/projects/{{ project.project_id }}/slides/${slideIndex}/save`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(requestData)
                });

                console.log(`📥 服务器响应状态: ${response.status} ${response.statusText}`);

                if (!response.ok) {
                    const errorText = await response.text();
                    console.error(`❌ HTTP错误响应:`, errorText);
                    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
                }

                const data = await response.json();
                console.log(`✅ 服务器响应数据:`, data);

                // 验证保存是否成功
                if (data.success === true) {
                    console.log(`✅ 第${slideIndex + 1}页保存成功！数据库已更新`);
                    return true;
                } else {
                    console.error(`❌ 保存失败:`, data.error);
                    throw new Error(data.error || 'Unknown error occurred');
                }

            } catch (error) {
                console.error(`❌ 保存第${slideIndex + 1}页时发生错误:`, error);
                console.error(`❌ 错误详情:`, {
                    slideIndex: slideIndex,
                    totalSlides: slidesData ? slidesData.length : 'undefined',
                    currentSlideIndex: currentSlideIndex,
                    error: error.message
                });
                throw error; // 重新抛出错误以便调用者处理
            }
        }

        function exportToPDF() {
            // 显示提示信息
            showNotification('正在生成PDF文件...', 'info');

            // 直接下载PDF文件
            const downloadLink = document.createElement('a');
            downloadLink.href = `/api/projects/{{ project.project_id }}/export/pdf`;
            downloadLink.download = '';
            downloadLink.style.display = 'none';

            // 添加到页面并触发下载
            document.body.appendChild(downloadLink);
            downloadLink.click();
            document.body.removeChild(downloadLink);

            // 延迟显示成功消息
            setTimeout(() => {
                showNotification('PDF文件生成完成，正在下载...', 'success');
            }, 1000);
        }



        function exportToPDFClientSide() {
            // 显示提示信息
            // showNotification('正在打开客户端PDF导出页面...', 'info');

            // 打开客户端PDF导出页面（原html2pdf.js方式）
           // window.open(`/api/projects/{{ project.project_id }}/export/pdf?fallback=true`, '_blank');
        }

        function exportToPPTX() {
            // 显示提示信息
            showNotification('正在生成PPTX文件...', 'info');
            showNotification('此过程需要先生成PDF再转换为PPTX，请耐心等待...', 'warning');

            // 直接下载PPTX文件
            const downloadLink = document.createElement('a');
            downloadLink.href = `/api/projects/{{ project.project_id }}/export/pptx`;
            downloadLink.download = '';
            downloadLink.style.display = 'none';

            // 添加到页面并触发下载
            document.body.appendChild(downloadLink);
            downloadLink.click();
            document.body.removeChild(downloadLink);

            // 延迟显示成功消息
            setTimeout(() => {
                showNotification('PPTX文件生成完成，正在下载...', 'success');
            }, 2000);
        }

        function downloadHTML() {
            // 显示提示信息
            showNotification('正在准备HTML文件包...', 'info');

            // 创建下载链接
            const downloadLink = document.createElement('a');
            downloadLink.href = `/api/projects/{{ project.project_id }}/export/html`;
            downloadLink.download = '';
            downloadLink.style.display = 'none';

            // 添加到页面并触发下载
            document.body.appendChild(downloadLink);
            downloadLink.click();
            document.body.removeChild(downloadLink);

            // 延迟显示成功消息
            setTimeout(() => {
                showNotification('HTML文件包下载已开始', 'success');
            }, 1000);
        }

        function showNotification(message, type = 'info') {
            // 创建通知元素
            const notification = document.createElement('div');
            notification.className = `notification notification-${type}`;
            notification.textContent = message;

            // 添加样式
            notification.style.cssText = `
                position: fixed;
                top: 20px;
                right: 20px;
                padding: 12px 20px;
                border-radius: 6px;
                color: white;
                font-weight: 500;
                z-index: 10000;
                opacity: 0;
                transform: translateX(100%);
                transition: all 0.3s ease;
            `;

            // 根据类型设置背景色
            switch(type) {
                case 'success':
                    notification.style.backgroundColor = '#28a745';
                    break;
                case 'error':
                    notification.style.backgroundColor = '#dc3545';
                    break;
                case 'warning':
                    notification.style.backgroundColor = '#ffc107';
                    notification.style.color = '#212529';
                    break;
                default:
                    notification.style.backgroundColor = '#007bff';
            }

            // 添加到页面
            document.body.appendChild(notification);

            // 显示动画
            setTimeout(() => {
                notification.style.opacity = '1';
                notification.style.transform = 'translateX(0)';
            }, 100);

            // 自动隐藏
            setTimeout(() => {
                notification.style.opacity = '0';
                notification.style.transform = 'translateX(100%)';
                setTimeout(() => {
                    if (notification.parentNode) {
                        notification.parentNode.removeChild(notification);
                    }
                }, 300);
            }, 3000);
        }

        function exportSingleSlideHTML() {
            hideContextMenu();
            if (contextMenuSlideIndex >= 0 && contextMenuSlideIndex < slidesData.length) {
                const slide = slidesData[contextMenuSlideIndex];
                if (slide && slide.html_content) {
                    // Create a blob with the HTML content
                    const blob = new Blob([slide.html_content], { type: 'text/html' });

                    // Create download link
                    const url = URL.createObjectURL(blob);
                    const a = document.createElement('a');
                    a.href = url;
                    a.download = `slide_${contextMenuSlideIndex + 1}_${slide.title || 'untitled'}.html`;

                    // Trigger download
                    document.body.appendChild(a);
                    a.click();
                    document.body.removeChild(a);

                    // Clean up
                    URL.revokeObjectURL(url);

                    alert(`第${contextMenuSlideIndex + 1}页已导出为HTML文件`);
                } else {
                    alert('该幻灯片没有可导出的HTML内容');
                }
            }
        }

        function sharePresentation() {
            const shareUrl = `${window.location.origin}/projects/{{ project.project_id }}/fullscreen`;

            // 创建分享对话框
            const modal = document.createElement('div');
            modal.style.cssText = `
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background: rgba(0,0,0,0.5);
                display: flex;
                justify-content: center;
                align-items: center;
                z-index: 10000;
            `;

            modal.innerHTML = `
                <div style="
                    background: white;
                    padding: 30px;
                    border-radius: 15px;
                    max-width: 500px;
                    width: 90%;
                    text-align: center;
                    box-shadow: 0 10px 30px rgba(0,0,0,0.3);
                ">
                    <h4 style="margin-bottom: 20px; color: #2c3e50;">
                        <i class="fas fa-share" style="color: #007bff;"></i> 分享演示
                    </h4>
                    <p style="margin-bottom: 20px; color: #666;">
                        使用以下链接分享您的PPT演示，观众可以在任何设备上观看
                    </p>
                    <div style="
                        background: #f8f9fa;
                        padding: 15px;
                        border-radius: 8px;
                        margin-bottom: 20px;
                        border: 1px solid #dee2e6;
                        word-break: break-all;
                        font-family: monospace;
                        font-size: 14px;
                    ">${shareUrl}</div>
                    <div style="display: flex; gap: 10px; justify-content: center;">
                        <button onclick="copyShareUrl('${shareUrl}')" class="btn btn-primary">
                            <i class="fas fa-copy"></i> 复制链接
                        </button>
                        <button onclick="openShareUrl('${shareUrl}')" class="btn btn-success">
                            <i class="fas fa-external-link-alt"></i> 打开演示
                        </button>
                        <button onclick="this.closest('.share-modal').remove()" class="btn btn-secondary">
                            <i class="fas fa-times"></i> 关闭
                        </button>
                    </div>
                    <div style="margin-top: 15px; font-size: 12px; color: #999;">
                        <i class="fas fa-info-circle"></i> 演示会自动使用数据库中最新的幻灯片内容
                    </div>
                </div>
            `;

            modal.className = 'share-modal';
            document.body.appendChild(modal);

            // 点击背景关闭
            modal.addEventListener('click', function(e) {
                if (e.target === modal) {
                    modal.remove();
                }
            });
        }

        function copyShareUrl(url) {
            navigator.clipboard.writeText(url).then(() => {
                showNotification('分享链接已复制到剪贴板！', 'success');
            }).catch(() => {
                // 备用复制方法
                const textArea = document.createElement('textarea');
                textArea.value = url;
                document.body.appendChild(textArea);
                textArea.select();
                document.execCommand('copy');
                document.body.removeChild(textArea);
                showNotification('分享链接已复制到剪贴板！', 'success');
            });
        }

        function openShareUrl(url) {
            window.open(url, '_blank');
        }

        // Auto-save on code change (fallback for non-CodeMirror mode)
        function initializeCodeEditorAutoSave() {
            const codeEditor = document.getElementById('codeEditor');
            if (codeEditor && !isCodeMirrorInitialized) {
                codeEditor.addEventListener('input', function() {
                    clearTimeout(this.saveTimeout);
                    this.saveTimeout = setTimeout(() => {
                        if (currentMode === 'split') {
                            // Auto-update preview in split mode
                            const slideFrame = document.getElementById('slideFrame');
                            setSafeIframeContent(slideFrame, this.value);
                        }
                    }, 1000);
                });
            }
        }

        // Initialize event listeners for thumbnails using event delegation
        function initializeThumbnailEvents() {
            // Use event delegation on the slides container
            const slidesContainer = document.querySelector('.slides-container');
            if (!slidesContainer) {
                console.log('Slides container not found');
                return;
            }

            // Remove existing event listeners to prevent duplicates
            slidesContainer.removeEventListener('click', slidesContainer.clickHandler);
            slidesContainer.removeEventListener('contextmenu', slidesContainer.contextHandler);
            slidesContainer.removeEventListener('dragstart', slidesContainer.dragStartHandler);
            slidesContainer.removeEventListener('dragover', slidesContainer.dragOverHandler);
            slidesContainer.removeEventListener('drop', slidesContainer.dropHandler);
            slidesContainer.removeEventListener('dragend', slidesContainer.dragEndHandler);

            // Create event handlers using event delegation
            slidesContainer.clickHandler = (e) => {
                const thumbnail = e.target.closest('.slide-thumbnail');
                if (thumbnail) {
                    e.preventDefault();
                    e.stopPropagation();
                    const index = parseInt(thumbnail.getAttribute('data-slide-index'));
                    if (!isNaN(index)) {
                        selectSlide(index);
                    }
                }
            };

            slidesContainer.contextHandler = (e) => {
                const thumbnail = e.target.closest('.slide-thumbnail');
                if (thumbnail) {
                    e.preventDefault();
                    const index = parseInt(thumbnail.getAttribute('data-slide-index'));
                    if (!isNaN(index)) {
                        showContextMenu(e, index);
                    }
                }
            };

            slidesContainer.dragStartHandler = (e) => {
                const thumbnail = e.target.closest('.slide-thumbnail');
                if (thumbnail) {
                    const index = parseInt(thumbnail.getAttribute('data-slide-index'));
                    if (!isNaN(index)) {
                        handleDragStart(e, index);
                    }
                }
            };

            slidesContainer.dragOverHandler = (e) => {
                const thumbnail = e.target.closest('.slide-thumbnail');
                if (thumbnail) {
                    handleDragOver(e);
                }
            };

            slidesContainer.dropHandler = (e) => {
                const thumbnail = e.target.closest('.slide-thumbnail');
                if (thumbnail) {
                    const index = parseInt(thumbnail.getAttribute('data-slide-index'));
                    if (!isNaN(index)) {
                        handleDrop(e, index);
                    }
                }
            };

            slidesContainer.dragEndHandler = (e) => {
                const thumbnail = e.target.closest('.slide-thumbnail');
                if (thumbnail) {
                    handleDragEnd(e);
                }
            };

            // Add event listeners using delegation
            slidesContainer.addEventListener('click', slidesContainer.clickHandler);
            slidesContainer.addEventListener('contextmenu', slidesContainer.contextHandler);
            slidesContainer.addEventListener('dragstart', slidesContainer.dragStartHandler);
            slidesContainer.addEventListener('dragover', slidesContainer.dragOverHandler);
            slidesContainer.addEventListener('drop', slidesContainer.dropHandler);
            slidesContainer.addEventListener('dragend', slidesContainer.dragEndHandler);
        }

        // 优化的幻灯片放映功能 - 双缓冲无闪烁系统
        let slideshowCache = new Map(); // 缓存幻灯片内容
        let isTransitioning = false; // 防止快速切换时的重复操作
        let currentFrameIndex = 1; // 当前显示的iframe索引 (1 或 2)
        let nextFrameIndex = 2; // 下一个iframe索引 (1 或 2)

        function startSlideshow() {
            if (!slidesData || slidesData.length === 0) {
                showNotification('没有可用的幻灯片！', 'warning');
                return;
            }

            isSlideshow = true;
            slideshowIndex = currentSlideIndex;

            // 重置双缓冲系统
            currentFrameIndex = 1;
            nextFrameIndex = 2;

            const overlay = document.getElementById('slideshowOverlay');
            const frame1 = document.getElementById('slideshowFrame1');
            const frame2 = document.getElementById('slideshowFrame2');

            // 初始化iframe状态
            frame1.classList.add('visible');
            frame1.classList.remove('hidden');
            frame2.classList.add('hidden');
            frame2.classList.remove('visible');

            // 使用requestAnimationFrame优化显示
            requestAnimationFrame(() => {
                overlay.style.display = 'flex';

                // 预加载当前和下一张幻灯片
                preloadSlideshowSlides();

                // 在第一个iframe中加载当前幻灯片
                const content = slideshowCache.get(slideshowIndex) || slidesData[slideshowIndex].html_content;
                setSafeIframeContentNoFlash(frame1, content, () => {
                    // 更新幻灯片信息
                    const info = document.getElementById('slideshowInfo');
                    info.textContent = `${slideshowIndex + 1} / ${slidesData.length}`;
                });
            });

            // Add keyboard event listeners
            document.addEventListener('keydown', handleSlideshowKeyboard);

            // Add touch gesture support
            initializeSlideshowTouchGestures();
        }

        // 预加载幻灯片内容，提升切换流畅度
        function preloadSlideshowSlides() {
            // 预加载当前、前一张和后一张幻灯片
            const indicesToPreload = [
                slideshowIndex - 1,
                slideshowIndex,
                slideshowIndex + 1
            ].filter(index => index >= 0 && index < slidesData.length);

            indicesToPreload.forEach(index => {
                if (!slideshowCache.has(index)) {
                    const content = slidesData[index].html_content;
                    slideshowCache.set(index, content);
                }
            });
        }

        function exitSlideshow() {
            isSlideshow = false;
            isTransitioning = false;

            const overlay = document.getElementById('slideshowOverlay');
            const frame1 = document.getElementById('slideshowFrame1');
            const frame2 = document.getElementById('slideshowFrame2');

            // 使用fade out效果
            overlay.style.opacity = '0';
            setTimeout(() => {
                overlay.style.display = 'none';
                overlay.style.opacity = '1';

                // 清理iframe内容，避免内存泄漏
                frame1.srcdoc = '';
                frame2.srcdoc = '';
                frame1.removeAttribute('data-current-content');
                frame2.removeAttribute('data-current-content');
            }, 200);

            // Remove keyboard event listeners
            document.removeEventListener('keydown', handleSlideshowKeyboard);

            // Remove touch gesture listeners
            removeSlideshowTouchGestures();

            // 清理缓存（可选，节省内存）
            slideshowCache.clear();
        }

        // 无闪烁幻灯片更新函数 - 双缓冲系统
        function updateSlideshowSlide() {
            if (!slidesData || slidesData.length === 0 || isTransitioning) return;

            isTransitioning = true;

            const info = document.getElementById('slideshowInfo');

            // 立即更新幻灯片信息
            info.textContent = `${slideshowIndex + 1} / ${slidesData.length}`;

            // 获取当前显示的iframe和下一个iframe
            const currentFrame = document.getElementById(`slideshowFrame${currentFrameIndex}`);
            const nextFrame = document.getElementById(`slideshowFrame${nextFrameIndex}`);

            // 在后台iframe中预加载新内容
            const content = slideshowCache.get(slideshowIndex) || slidesData[slideshowIndex].html_content;

            // 使用优化的内容设置方法
            setSafeIframeContentNoFlash(nextFrame, content, () => {
                // 内容加载完成后，瞬间切换显示
                requestAnimationFrame(() => {
                    // 隐藏当前iframe，显示新iframe
                    currentFrame.classList.remove('visible');
                    currentFrame.classList.add('hidden');
                    nextFrame.classList.remove('hidden');
                    nextFrame.classList.add('visible');

                    // 交换iframe索引
                    [currentFrameIndex, nextFrameIndex] = [nextFrameIndex, currentFrameIndex];

                    isTransitioning = false;

                    // 预加载相邻幻灯片
                    preloadSlideshowSlides();

                    // 异步初始化JavaScript，不阻塞UI
                    setTimeout(() => {
                        forceReinitializeIframeJS(nextFrame);
                    }, 100);
                });
            });
        }

        // 优化的iframe内容设置，避免闪烁
        function setSafeIframeContentNoFlash(iframe, html, callback) {
            if (!iframe || !html) {
                if (callback) callback();
                return;
            }

            // 检查内容是否相同，避免不必要的更新
            if (iframe.getAttribute('data-current-content') === html) {
                if (callback) callback();
                return;
            }

            // 直接设置内容，不使用过渡效果
            try {
                iframe.srcdoc = html;
                iframe.setAttribute('data-current-content', html);

                // 监听加载完成
                const handleLoad = () => {
                    iframe.removeEventListener('load', handleLoad);
                    if (callback) {
                        // 短暂延迟确保内容完全渲染
                        setTimeout(callback, 50);
                    }
                };

                iframe.addEventListener('load', handleLoad);

                // 备用超时机制
                setTimeout(() => {
                    iframe.removeEventListener('load', handleLoad);
                    if (callback) callback();
                }, 500);

            } catch (e) {
                console.warn('设置iframe内容失败:', e);
                if (callback) callback();
            }
        }

        // 优化的切换函数，支持快速响应和防抖
        function previousSlideshow() {
            if (isTransitioning) return; // 防止快速切换时的重复操作

            if (slideshowIndex > 0) {
                slideshowIndex--;
                updateSlideshowSlide();
            } else {
                // 到达第一张时的视觉反馈
                const slideContainer = document.querySelector('.slideshow-slide');
                slideContainer.style.transform = 'translateX(-10px)';
                setTimeout(() => {
                    slideContainer.style.transform = 'translateX(0)';
                }, 150);
            }
        }

        function nextSlideshow() {
            if (isTransitioning) return; // 防止快速切换时的重复操作

            if (slideshowIndex < slidesData.length - 1) {
                slideshowIndex++;
                updateSlideshowSlide();
            } else {
                // 到达最后一张时的视觉反馈
                const slideContainer = document.querySelector('.slideshow-slide');
                slideContainer.style.transform = 'translateX(10px)';
                setTimeout(() => {
                    slideContainer.style.transform = 'translateX(0)';
                }, 150);
            }
        }

        // 快速跳转到指定幻灯片
        function jumpToSlide(index) {
            if (isTransitioning || index < 0 || index >= slidesData.length) return;

            slideshowIndex = index;
            updateSlideshowSlide();
        }

        // 优化的键盘事件处理，支持更多快捷键和防抖
        let keyboardTimeout;

        function handleSlideshowKeyboard(e) {
            if (!isSlideshow) return;

            // 防抖处理，避免按键过快
            clearTimeout(keyboardTimeout);
            keyboardTimeout = setTimeout(() => {
                switch(e.key) {
                    case 'ArrowLeft':
                    case 'ArrowUp':
                    case 'PageUp':
                    case 'Backspace':
                        e.preventDefault();
                        previousSlideshow();
                        break;
                    case 'ArrowRight':
                    case 'ArrowDown':
                    case 'PageDown':
                    case ' ':
                    case 'Enter':
                        e.preventDefault();
                        nextSlideshow();
                        break;
                    case 'Escape':
                    case 'q':
                    case 'Q':
                        e.preventDefault();
                        exitSlideshow();
                        break;
                    case 'Home':
                        e.preventDefault();
                        jumpToSlide(0);
                        break;
                    case 'End':
                        e.preventDefault();
                        jumpToSlide(slidesData.length - 1);
                        break;
                    case 'f':
                    case 'F':
                    case 'F11':
                        e.preventDefault();
                        toggleSlideshowFullscreen();
                        break;
                    default:
                        // 数字键快速跳转
                        if (e.key >= '1' && e.key <= '9') {
                            e.preventDefault();
                            const slideNum = parseInt(e.key) - 1;
                            if (slideNum < slidesData.length) {
                                jumpToSlide(slideNum);
                            }
                        }
                        break;
                }
            }, 50); // 50ms防抖
        }

        // 全屏切换功能
        function toggleSlideshowFullscreen() {
            const overlay = document.getElementById('slideshowOverlay');

            if (!document.fullscreenElement) {
                overlay.requestFullscreen().catch(err => {
                    console.log('无法进入全屏:', err);
                });
            } else {
                document.exitFullscreen().catch(err => {
                    console.log('无法退出全屏:', err);
                });
            }
        }

        // 拖拽功能
        function handleDragStart(event, slideIndex) {
            draggedSlideIndex = slideIndex;
            event.target.classList.add('dragging');
            event.dataTransfer.effectAllowed = 'move';
            event.dataTransfer.setData('text/html', event.target.outerHTML);
        }

        function handleDragOver(event) {
            event.preventDefault();
            event.dataTransfer.dropEffect = 'move';

            const thumbnail = event.currentTarget;
            const rect = thumbnail.getBoundingClientRect();
            const midY = rect.top + rect.height / 2;

            // 清除所有指示器
            document.querySelectorAll('.drag-indicator').forEach(indicator => {
                indicator.classList.remove('show');
            });

            // 显示适当的指示器
            if (event.clientY < midY) {
                thumbnail.querySelector('.drag-indicator.top').classList.add('show');
            } else {
                thumbnail.querySelector('.drag-indicator.bottom').classList.add('show');
            }

            thumbnail.classList.add('drag-over');
        }

        function handleDrop(event, targetIndex) {
            event.preventDefault();

            if (draggedSlideIndex === -1 || draggedSlideIndex === targetIndex) {
                return;
            }

            const rect = event.currentTarget.getBoundingClientRect();
            const midY = rect.top + rect.height / 2;
            const insertBefore = event.clientY < midY;

            // 计算新的插入位置
            let newIndex = targetIndex;
            if (!insertBefore) {
                newIndex = targetIndex + 1;
            }

            // 如果拖拽的元素在目标位置之前，需要调整索引
            if (draggedSlideIndex < newIndex) {
                newIndex--;
            }

            // 移动幻灯片
            moveSlide(draggedSlideIndex, newIndex);
        }

        function handleDragEnd(event) {
            event.target.classList.remove('dragging');
            document.querySelectorAll('.slide-thumbnail').forEach(thumb => {
                thumb.classList.remove('drag-over');
            });
            document.querySelectorAll('.drag-indicator').forEach(indicator => {
                indicator.classList.remove('show');
            });
            draggedSlideIndex = -1;
        }

        function moveSlide(fromIndex, toIndex) {
            if (fromIndex === toIndex || fromIndex < 0 || toIndex < 0 ||
                fromIndex >= slidesData.length || toIndex > slidesData.length) {
                return;
            }

            // 移动数据
            const movedSlide = slidesData.splice(fromIndex, 1)[0];
            slidesData.splice(toIndex, 0, movedSlide);

            // 更新页码
            slidesData.forEach((slide, index) => {
                slide.page_number = index + 1;
            });

            // 更新当前选中的索引
            if (currentSlideIndex === fromIndex) {
                currentSlideIndex = toIndex;
            } else if (currentSlideIndex > fromIndex && currentSlideIndex <= toIndex) {
                currentSlideIndex--;
            } else if (currentSlideIndex < fromIndex && currentSlideIndex >= toIndex) {
                currentSlideIndex++;
            }

            // 重新渲染侧边栏
            refreshSidebar();

            // 保存到服务器
            saveToServer();
        }

        // 右键菜单功能
        function showContextMenu(event, slideIndex) {
            event.preventDefault();
            contextMenuSlideIndex = slideIndex;

            const contextMenu = document.getElementById('contextMenu');
            const pasteMenuItem = document.getElementById('pasteMenuItem');

            // 更新粘贴菜单项状态
            if (copiedSlideData) {
                pasteMenuItem.classList.remove('disabled');
            } else {
                pasteMenuItem.classList.add('disabled');
            }

            // 显示菜单
            contextMenu.style.display = 'block';
            contextMenu.style.left = event.pageX + 'px';
            contextMenu.style.top = event.pageY + 'px';

            // 确保菜单不超出屏幕
            const rect = contextMenu.getBoundingClientRect();
            if (rect.right > window.innerWidth) {
                contextMenu.style.left = (event.pageX - rect.width) + 'px';
            }
            if (rect.bottom > window.innerHeight) {
                contextMenu.style.top = (event.pageY - rect.height) + 'px';
            }
        }

        function hideContextMenu() {
            document.getElementById('contextMenu').style.display = 'none';
        }

        function editSlide() {
            hideContextMenu();
            selectSlide(contextMenuSlideIndex);
            setMode('edit');
        }

        function copySlide() {
            hideContextMenu();
            if (!isPPTGenerationCompleted()) {
                showNotification('PPT生成完成后才能使用复制功能', 'warning');
                return;
            }
            if (contextMenuSlideIndex >= 0 && contextMenuSlideIndex < slidesData.length) {
                copiedSlideData = JSON.parse(JSON.stringify(slidesData[contextMenuSlideIndex]));
                showNotification('幻灯片已复制到剪贴板', 'success');
            }
        }

        async function pasteSlide() {
            hideContextMenu();
            if (!isPPTGenerationCompleted()) {
                showNotification('PPT生成完成后才能使用粘贴功能', 'warning');
                return;
            }
            if (!copiedSlideData) {
                showNotification('剪贴板中没有幻灯片数据', 'warning');
                return;
            }

            try {
                // 获取全局母版模板
                const globalTemplate = await getSelectedGlobalTemplate();

                // 创建新的幻灯片数据
                const newSlide = JSON.parse(JSON.stringify(copiedSlideData));
                newSlide.page_number = contextMenuSlideIndex + 2;
                newSlide.title = newSlide.title + ' (副本)';

                // 如果有全局母版，使用模板生成新的HTML内容
                if (globalTemplate) {
                    newSlide.html_content = await generateSlideWithGlobalTemplate(
                        globalTemplate,
                        newSlide.title,
                        '复制的幻灯片内容'
                    );
                }

                // 插入到指定位置
                slidesData.splice(contextMenuSlideIndex + 1, 0, newSlide);

                // 更新后续幻灯片的页码
                for (let i = contextMenuSlideIndex + 2; i < slidesData.length; i++) {
                    slidesData[i].page_number = i + 1;
                }

                // 同步更新大纲
                await updateOutlineForSlideOperation('insert', contextMenuSlideIndex + 1, {
                    title: newSlide.title,
                    slide_type: 'content',
                    type: 'content',
                    description: '复制的幻灯片内容',
                    content_points: []
                });

                // 刷新界面
                refreshSidebar();
                saveToServer();
                showNotification('幻灯片已粘贴', 'success');
            } catch (error) {
                console.error('粘贴幻灯片失败:', error);
                showNotification('粘贴幻灯片失败：' + error.message, 'error');
            }
        }

        async function insertNewSlide() {
            hideContextMenu();
            if (!isPPTGenerationCompleted()) {
                showNotification('PPT生成完成后才能添加新幻灯片', 'warning');
                return;
            }

            try {
                // 获取全局母版模板
                const globalTemplate = await getSelectedGlobalTemplate();

                const slideTitle = `第${contextMenuSlideIndex + 2}页`;
                let htmlContent = `
                    <div style="width: 1280px; height: 720px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
                                display: flex; flex-direction: column; justify-content: center; align-items: center;
                                color: white; font-family: 'Microsoft YaHei', Arial, sans-serif;">
                        <h1 style="font-size: 48px; margin-bottom: 20px; text-align: center;">新建幻灯片</h1>
                        <p style="font-size: 24px; text-align: center;">请编辑此幻灯片内容</p>
                    </div>
                `;

                // 如果有全局母版，使用模板生成HTML内容
                if (globalTemplate) {
                    htmlContent = await generateSlideWithGlobalTemplate(
                        globalTemplate,
                        slideTitle,
                        '新建幻灯片，请编辑内容'
                    );
                }

                // 创建新的空白幻灯片
                const newSlide = {
                    page_number: contextMenuSlideIndex + 2,
                    title: slideTitle,
                    html_content: htmlContent
                };

                // 插入到指定位置
                slidesData.splice(contextMenuSlideIndex + 1, 0, newSlide);

                // 更新后续幻灯片的页码
                for (let i = contextMenuSlideIndex + 2; i < slidesData.length; i++) {
                    slidesData[i].page_number = i + 1;
                }

                // 同步更新大纲
                await updateOutlineForSlideOperation('insert', contextMenuSlideIndex + 1, {
                    title: slideTitle,
                    slide_type: 'content',
                    type: 'content',
                    description: '新建幻灯片，请编辑内容',
                    content_points: []
                });

                // 刷新界面
                refreshSidebar();
                saveToServer();
                showNotification('新幻灯片已插入', 'success');
            } catch (error) {
                console.error('插入新幻灯片失败:', error);
                showNotification('插入新幻灯片失败：' + error.message, 'error');
            }
        }

        async function duplicateSlide() {
            hideContextMenu();
            if (!isPPTGenerationCompleted()) {
                showNotification('PPT生成完成后才能复制幻灯片', 'warning');
                return;
            }
            if (contextMenuSlideIndex >= 0 && contextMenuSlideIndex < slidesData.length) {
                try {
                    // 获取全局母版模板
                    const globalTemplate = await getSelectedGlobalTemplate();

                    const originalSlide = slidesData[contextMenuSlideIndex];
                    const duplicatedSlide = JSON.parse(JSON.stringify(originalSlide));
                    duplicatedSlide.page_number = contextMenuSlideIndex + 2;
                    duplicatedSlide.title = duplicatedSlide.title + ' (副本)';

                    // 如果有全局母版，使用模板重新生成HTML内容
                    if (globalTemplate) {
                        duplicatedSlide.html_content = await generateSlideWithGlobalTemplate(
                            globalTemplate,
                            duplicatedSlide.title,
                            '复制的幻灯片内容'
                        );
                    }

                    // 插入到原幻灯片后面
                    slidesData.splice(contextMenuSlideIndex + 1, 0, duplicatedSlide);

                    // 更新后续幻灯片的页码
                    for (let i = contextMenuSlideIndex + 2; i < slidesData.length; i++) {
                        slidesData[i].page_number = i + 1;
                    }

                    // 同步更新大纲
                    await updateOutlineForSlideOperation('insert', contextMenuSlideIndex + 1, {
                        title: duplicatedSlide.title,
                        slide_type: 'content',
                        type: 'content',
                        description: '复制的幻灯片内容',
                        content_points: []
                    });

                    // 刷新界面
                    refreshSidebar();
                    saveToServer();
                    showNotification('幻灯片已复制', 'success');
                } catch (error) {
                    console.error('复制幻灯片失败:', error);
                    showNotification('复制幻灯片失败：' + error.message, 'error');
                }
            }
        }

        async function deleteSlide() {
            hideContextMenu();
            if (!isPPTGenerationCompleted()) {
                showNotification('PPT生成完成后才能删除幻灯片', 'warning');
                return;
            }
            if (slidesData.length <= 1) {
                showNotification('至少需要保留一张幻灯片', 'warning');
                return;
            }

            if (confirm('确定要删除这张幻灯片吗？')) {
                try {
                    // 删除幻灯片
                    slidesData.splice(contextMenuSlideIndex, 1);

                    // 更新后续幻灯片的页码
                    for (let i = contextMenuSlideIndex; i < slidesData.length; i++) {
                        slidesData[i].page_number = i + 1;
                    }

                    // 调整当前选中的索引
                    if (currentSlideIndex >= contextMenuSlideIndex) {
                        currentSlideIndex = Math.max(0, currentSlideIndex - 1);
                    }

                    // 同步更新大纲
                    await updateOutlineForSlideOperation('delete', contextMenuSlideIndex);

                    // 刷新界面
                    refreshSidebar();
                    selectSlide(currentSlideIndex);

                    // 保存当前幻灯片数据
                    await saveToServer();

                    // 清理数据库中多余的幻灯片
                    await cleanupExcessSlides();

                    showNotification('幻灯片已删除', 'success');
                } catch (error) {
                    console.error('删除幻灯片失败:', error);
                    showNotification('删除幻灯片失败：' + error.message, 'error');
                }
            }
        }

        function refreshSidebar() {
            const slidesContainer = document.querySelector('.slides-container');
            if (!slidesContainer) return;

            // 如果没有slides数据，显示提示信息
            if (!slidesData || slidesData.length === 0) {
                slidesContainer.innerHTML = `
                    <div class="text-center p-4" style="color: #7f8c8d;" id="noSlidesMessage">
                        <div style="font-size: 48px; margin-bottom: 15px;">
                            <i class="fas fa-magic"></i>
                        </div>
                        <h5 style="margin-bottom: 10px;">PPT正在生成中...</h5>
                        <p style="margin-bottom: 15px; font-size: 14px;">
                            幻灯片生成完成后，您可以在这里进行编辑和管理
                        </p>
                        <div class="spinner-border text-primary" role="status" style="margin-bottom: 15px;">
                            <span class="visually-hidden">Loading...</span>
                        </div>
                        <br>
                        <button class="btn btn-primary btn-sm" onclick="checkForUpdates()">
                            <i class="fas fa-refresh"></i> 刷新页面
                        </button>
                    </div>
                `;
                return;
            }

            // 清除现有的幻灯片缩略图和提示信息
            const existingThumbnails = slidesContainer.querySelectorAll('.slide-thumbnail');
            const noSlidesMessage = slidesContainer.querySelector('#noSlidesMessage');
            existingThumbnails.forEach(thumb => thumb.remove());
            if (noSlidesMessage) noSlidesMessage.remove();

            // 重新生成幻灯片缩略图
            slidesData.forEach((slide, index) => {
                const thumbnailDiv = document.createElement('div');
                thumbnailDiv.className = `slide-thumbnail ${index === currentSlideIndex ? 'active' : ''}`;
                thumbnailDiv.setAttribute('data-slide-index', index);
                thumbnailDiv.setAttribute('draggable', 'true');
                // 不再使用内联事件处理器，依赖事件委托

                thumbnailDiv.innerHTML = `
                    <div class="drag-indicator top"></div>
                    <div class="slide-preview">
                        <iframe title="Slide ${index + 1}"
                                loading="lazy"></iframe>
                    </div>
                    <div class="slide-title">${index + 1}. ${slide.title}</div>
                    <div class="drag-indicator bottom"></div>
                `;

                // 设置iframe内容并应用缩放
                const iframe = thumbnailDiv.querySelector('iframe');
                if (iframe) {
                    // 安全设置iframe内容
                    setSafeIframeContent(iframe, slide.html_content);

                    iframe.onload = function() {
                        // 应用响应式缩放
                        this.style.transform = getResponsiveScale();
                        this.style.width = getResponsiveWidth();
                        this.style.height = getResponsiveHeight();
                    };
                }

                slidesContainer.appendChild(thumbnailDiv);
            });

            // 重新初始化事件监听器
            initializeThumbnailEvents();
        }

        // 优化的iframe JavaScript重新初始化函数
        let isReinitializing = false; // 防止重复初始化

        function forceReinitializeIframeJS(iframe) {
            if (!iframe || isReinitializing) return;

            isReinitializing = true;

            // 使用requestAnimationFrame优化性能
            requestAnimationFrame(() => {
                try {
                    const iframeWindow = iframe.contentWindow;
                    const iframeDoc = iframe.contentDocument || iframeWindow.document;

                    if (!iframeWindow || !iframeDoc) {
                        isReinitializing = false;
                        return;
                    }

                    // 只检查Chart.js，减少不必要的操作
                    if (iframeWindow.Chart) {
                        const canvasElements = iframeDoc.querySelectorAll('canvas[id*="chart"], canvas[id*="Chart"]');

                        if (canvasElements.length > 0) {
                            // 简化检查逻辑
                            let needsReinitialization = false;
                            canvasElements.forEach(canvas => {
                                if (!canvas.chart) {
                                    needsReinitialization = true;
                                }
                            });

                            // 只在真正需要时才重新初始化
                            if (needsReinitialization) {
                                const scripts = iframeDoc.querySelectorAll('script');
                                scripts.forEach(script => {
                                    if (script.textContent && script.textContent.includes('Chart')) {
                                        try {
                                            iframeWindow.eval(script.textContent);
                                        } catch (e) {
                                            // 静默处理错误
                                        }
                                    }
                                });
                            }
                        }
                    }

                    // 初始化图像选择功能
                    initializeImageSelection(iframe, iframeWindow, iframeDoc);

                } catch (e) {
                    // 静默处理错误，避免控制台噪音
                } finally {
                    // 延迟重置标志，避免过于频繁的调用
                    setTimeout(() => {
                        isReinitializing = false;
                    }, 500);
                }
            });
        }

        // 图像选择功能相关变量
        let selectedImageInfo = null;
        let imageSelectionEnabled = false;

        // 初始化图像选择功能（仅在快速编辑模式下启用）
        function initializeImageSelection(iframe, iframeWindow, iframeDoc) {
            try {
                // 移除之前的事件监听器
                const existingSelectables = iframeDoc.querySelectorAll('[data-image-selectable]');
                existingSelectables.forEach(element => {
                    element.removeAttribute('data-image-selectable');
                    element.style.cursor = '';
                    element.classList.remove('image-selected', 'image-selectable');
                    // 移除之前添加的事件监听器
                    if (element._imageClickHandler) {
                        element.removeEventListener('click', element._imageClickHandler);
                        element.removeEventListener('mouseenter', element._imageMouseEnterHandler);
                        element.removeEventListener('mouseleave', element._imageMouseLeaveHandler);
                        delete element._imageClickHandler;
                        delete element._imageMouseEnterHandler;
                        delete element._imageMouseLeaveHandler;
                    }
                });

                // 只在快速编辑模式下启用图像选择功能
                if (!quickEditMode || currentMode !== 'quickedit') {
                    console.log('图像选择功能仅在快速编辑模式下可用');
                    return;
                }

                let imageIndex = 0;

                // 1. 处理 <img> 标签
                const images = iframeDoc.querySelectorAll('img');
                images.forEach((img) => {
                    // 跳过装饰性图像或很小的图像
                    if (img.width < 30 || img.height < 30) return;

                    setupImageSelection(img, imageIndex++, iframe, 'img');
                });

                // 2. 处理具有背景图像的元素
                const allElements = iframeDoc.querySelectorAll('*');
                allElements.forEach((element) => {
                    const computedStyle = iframeWindow.getComputedStyle(element);
                    const backgroundImage = computedStyle.backgroundImage;

                    // 检查是否有背景图像（排除 none 和渐变）
                    if (backgroundImage &&
                        backgroundImage !== 'none' &&
                        backgroundImage.includes('url(')) {

                        // 获取元素尺寸
                        const rect = element.getBoundingClientRect();

                        // 跳过太小的元素
                        if (rect.width < 50 || rect.height < 50) return;

                        // 跳过已经处理过的img元素
                        if (element.tagName.toLowerCase() === 'img') return;

                        setupImageSelection(element, imageIndex++, iframe, 'background');
                    }
                });

                // 3. 处理SVG图像
                const svgElements = iframeDoc.querySelectorAll('svg');
                svgElements.forEach((svg) => {
                    const rect = svg.getBoundingClientRect();
                    if (rect.width < 30 || rect.height < 30) return;

                    setupImageSelection(svg, imageIndex++, iframe, 'svg');
                });

                // 添加样式到iframe文档
                addImageSelectionStyles(iframeDoc);

                if (imageIndex > 0) {
                    console.log(`图像选择功能已启用，共发现 ${imageIndex} 个可选择的图像元素`);
                } else {
                    console.log('当前幻灯片中没有可选择的图像元素');
                }

            } catch (e) {
                console.error('初始化图像选择功能失败:', e);
            }
        }

        // 设置单个元素的图像选择功能
        function setupImageSelection(element, index, iframe, type) {
            element.setAttribute('data-image-selectable', 'true');
            element.setAttribute('data-image-index', index);
            element.setAttribute('data-image-type', type);
            element.style.cursor = 'pointer';
            element.classList.add('image-selectable');

            // 创建事件处理器并保存引用以便后续移除
            element._imageClickHandler = function(e) {
                // 只在快速编辑模式下响应点击
                if (!quickEditMode || currentMode !== 'quickedit') {
                    return;
                }
                e.preventDefault();
                e.stopPropagation();
                selectImage(element, iframe);
            };

            element._imageMouseEnterHandler = function() {
                // 只在快速编辑模式下显示悬停效果
                if (!quickEditMode || currentMode !== 'quickedit') {
                    return;
                }
                if (!element.classList.contains('image-selected')) {
                    element.style.outline = '2px dashed #007bff';
                    element.style.outlineOffset = '2px';
                }
            };

            element._imageMouseLeaveHandler = function() {
                // 只在快速编辑模式下处理悬停离开
                if (!quickEditMode || currentMode !== 'quickedit') {
                    return;
                }
                if (!element.classList.contains('image-selected')) {
                    element.style.outline = '';
                    element.style.outlineOffset = '';
                }
            };

            // 添加事件监听器
            element.addEventListener('click', element._imageClickHandler);
            element.addEventListener('mouseenter', element._imageMouseEnterHandler);
            element.addEventListener('mouseleave', element._imageMouseLeaveHandler);
        }

        // 添加图像选择相关样式
        function addImageSelectionStyles(iframeDoc) {
            let styleElement = iframeDoc.getElementById('image-selection-styles');
            if (!styleElement) {
                styleElement = iframeDoc.createElement('style');
                styleElement.id = 'image-selection-styles';
                styleElement.textContent = `
                    .image-selectable {
                        transition: all 0.2s ease;
                    }
                    .image-selectable:hover {
                        transform: scale(1.02);
                    }
                    .image-selected {
                        outline: 3px solid #007bff !important;
                        outline-offset: 3px !important;
                        box-shadow: 0 0 10px rgba(0, 123, 255, 0.3) !important;
                        transform: scale(1.02) !important;
                    }
                `;
                iframeDoc.head.appendChild(styleElement);
            }
        }

        // 选择图像
        function selectImage(imgElement, iframe) {
            try {
                const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;

                // 清除之前的选择
                const previousSelected = iframeDoc.querySelectorAll('.image-selected');
                previousSelected.forEach(img => {
                    img.classList.remove('image-selected');
                    img.style.outline = '';
                    img.style.outlineOffset = '';
                    img.style.boxShadow = '';
                    img.style.transform = '';
                });

                // 选择当前图像
                imgElement.classList.add('image-selected');

                // 提取图像信息
                const imageInfo = extractImageInfo(imgElement, iframe);
                selectedImageInfo = imageInfo;

                // 通知AI助手
                notifyAIAssistantImageSelected(imageInfo);

                console.log('图像已选择:', imageInfo);

            } catch (e) {
                console.error('选择图像失败:', e);
            }
        }

        // 提取图像信息
        function extractImageInfo(imageElement, iframe) {
            const rect = imageElement.getBoundingClientRect();
            const computedStyle = iframe.contentWindow.getComputedStyle(imageElement);
            const imageType = imageElement.getAttribute('data-image-type') || 'img';

            let imageInfo = {
                index: imageElement.getAttribute('data-image-index'),
                type: imageType,
                className: imageElement.className,
                id: imageElement.id || '',
                style: imageElement.getAttribute('style') || '',
                width: rect.width,
                height: rect.height,
                position: {
                    top: rect.top,
                    left: rect.left,
                    right: rect.right,
                    bottom: rect.bottom
                },
                computedStyle: {
                    position: computedStyle.position,
                    display: computedStyle.display,
                    float: computedStyle.float,
                    margin: computedStyle.margin,
                    padding: computedStyle.padding,
                    border: computedStyle.border,
                    borderRadius: computedStyle.borderRadius,
                    transform: computedStyle.transform,
                    zIndex: computedStyle.zIndex,
                    opacity: computedStyle.opacity,
                    backgroundImage: computedStyle.backgroundImage,
                    backgroundSize: computedStyle.backgroundSize,
                    backgroundPosition: computedStyle.backgroundPosition,
                    backgroundRepeat: computedStyle.backgroundRepeat
                },
                slideIndex: currentSlideIndex,
                slideTitle: slidesData[currentSlideIndex]?.title || '',
                outerHTML: imageElement.outerHTML,
                parentInfo: extractParentInfo(imageElement)
            };

            // 根据图像类型提取特定信息
            if (imageType === 'img') {
                // <img> 标签的特定属性
                imageInfo.src = imageElement.src;
                imageInfo.alt = imageElement.alt || '';
                imageInfo.title = imageElement.title || '';
                imageInfo.naturalWidth = imageElement.naturalWidth;
                imageInfo.naturalHeight = imageElement.naturalHeight;
                imageInfo.computedStyle.objectFit = computedStyle.objectFit;
                imageInfo.computedStyle.objectPosition = computedStyle.objectPosition;
            } else if (imageType === 'background') {
                // 背景图像的特定属性
                const backgroundImage = computedStyle.backgroundImage;
                const urlMatch = backgroundImage.match(/url\(['"]?([^'"]+)['"]?\)/);
                imageInfo.src = urlMatch ? urlMatch[1] : '';
                imageInfo.alt = imageElement.getAttribute('alt') || imageElement.getAttribute('title') || '背景图像';
                imageInfo.title = imageElement.getAttribute('title') || '背景图像';
                imageInfo.isBackgroundImage = true;
            } else if (imageType === 'svg') {
                // SVG 的特定属性
                imageInfo.src = imageElement.getAttribute('src') || 'data:image/svg+xml;base64,' + btoa(imageElement.outerHTML);
                imageInfo.alt = imageElement.getAttribute('alt') || imageElement.getAttribute('title') || 'SVG图像';
                imageInfo.title = imageElement.getAttribute('title') || 'SVG图像';
                imageInfo.isSVG = true;
            }

            return imageInfo;
        }

        // 提取父容器信息
        function extractParentInfo(imgElement) {
            const parent = imgElement.parentElement;
            if (!parent) return null;

            return {
                tagName: parent.tagName,
                className: parent.className,
                style: parent.getAttribute('style') || '',
                id: parent.id || ''
            };
        }

        // 获取图像类型的显示名称
        function getImageTypeDisplay(type) {
            const typeMap = {
                'img': '图片标签',
                'background': '背景图像',
                'svg': 'SVG图像'
            };
            return typeMap[type] || '未知类型';
        }

        // 客户端图像替换函数（保持完整HTML结构）
        function replaceImageInHtmlClient(htmlContent, imageInfo, newImageUrl) {
            try {
                // 使用字符串替换而不是DOM解析，避免样式丢失
                const imageType = imageInfo.type || 'img';
                const oldSrc = imageInfo.src || '';

                let updatedHtml = htmlContent;
                let replaced = false;

                if (imageType === 'img') {
                    // 使用正则表达式替换img标签的src属性
                    const imgRegex = new RegExp(
                        `(<img[^>]*src=["'])[^"']*${escapeRegExp(oldSrc.split('/').pop())}[^"']*(['"][^>]*>)`,
                        'gi'
                    );

                    if (imgRegex.test(htmlContent)) {
                        updatedHtml = htmlContent.replace(imgRegex, `$1${newImageUrl}$2`);
                        replaced = true;
                    } else {
                        // 后备方案：直接字符串替换
                        if (htmlContent.includes(oldSrc)) {
                            updatedHtml = htmlContent.replace(new RegExp(escapeRegExp(oldSrc), 'g'), newImageUrl);
                            replaced = true;
                        }
                    }
                } else if (imageType === 'background') {
                    // 替换CSS背景图像
                    const bgRegex = new RegExp(
                        `(background-image:\\s*url\\(['"]?)[^'"\\)]*${escapeRegExp(oldSrc.split('/').pop())}[^'"\\)]*(['"]?\\))`,
                        'gi'
                    );

                    if (bgRegex.test(htmlContent)) {
                        updatedHtml = htmlContent.replace(bgRegex, `$1${newImageUrl}$2`);
                        replaced = true;
                    } else {
                        // 后备方案
                        if (htmlContent.includes(oldSrc)) {
                            updatedHtml = htmlContent.replace(new RegExp(escapeRegExp(oldSrc), 'g'), newImageUrl);
                            replaced = true;
                        }
                    }
                }

                return replaced ? updatedHtml : htmlContent;

            } catch (error) {
                console.error('客户端图像替换失败:', error);
                return htmlContent;
            }
        }

        // 搜索图片
        function searchImages(event) {
            if (event.key === 'Enter' || event.type === 'input') {
                galleryState.searchTerm = event.target.value.toLowerCase();
                galleryState.currentPage = 1;
                applyFilters();
            }
        }



        // 筛选图片分类
        function filterImages() {
            const categoryFilter = document.getElementById('imageCategoryFilter');
            galleryState.categoryFilter = categoryFilter.value;
            galleryState.currentPage = 1;
            applyFilters();
        }

        // 改变每页显示数量
        function changePageSize() {
            const pageSizeSelect = document.getElementById('imagePageSize');
            galleryState.pageSize = parseInt(pageSizeSelect.value);
            galleryState.currentPage = 1;
            renderImageGallery();
        }

        // 跳转到指定页面
        function goToPage(page) {
            const totalPages = Math.ceil(galleryState.filteredImages.length / galleryState.pageSize);
            if (page >= 1 && page <= totalPages) {
                galleryState.currentPage = page;
                renderImageGallery();
            }
        }

        // 应用筛选条件
        function applyFilters() {
            const { allImages, searchTerm, categoryFilter } = galleryState;

            galleryState.filteredImages = allImages.filter(image => {
                // 搜索筛选
                const matchesSearch = !searchTerm ||
                    (image.title && image.title.toLowerCase().includes(searchTerm)) ||
                    (image.description && image.description.toLowerCase().includes(searchTerm)) ||
                    (image.alt_text && image.alt_text.toLowerCase().includes(searchTerm));

                // 分类筛选 - 兼容多种可能的字段名
                let matchesCategory = true;
                if (categoryFilter) {
                    matchesCategory =
                        image.category === categoryFilter ||
                        image.source === categoryFilter ||
                        image.source_type === categoryFilter ||
                        image.type === categoryFilter ||
                        // 根据图片来源推断分类 - 修复字段映射
                        (categoryFilter === 'ai_generated' && (image.source === 'ai_generated' || image.source_type === 'ai_generated' || image.generation_prompt)) ||
                        (categoryFilter === 'network_search' && (image.source === 'web_search' || image.source_type === 'web_search')) ||
                        (categoryFilter === 'local_upload' && (image.source === 'local_storage' || image.source_type === 'local_storage'));
                }

                return matchesSearch && matchesCategory;
            });

            renderImageGallery();
        }

        // 双击图片直接选择
        function handleImageDoubleClick(imageData) {
            // 双击图片直接选择并关闭对话框
            window.closeGalleryDialog(imageData);
        }

        // 获取正确的图片URL
        function getImageUrl(image) {
            if (!image) return '';

            // 如果已经是完整URL，直接返回
            if (image.url && (image.url.startsWith('http') || image.url.startsWith('/api/'))) {
                return image.url;
            }

            // 如果有image.id，构建API URL
            if (image.id) {
                return `/api/image/view/${image.id}`;
            }

            // 如果有相对路径，转换为API URL
            if (image.url) {
                return image.url.startsWith('/') ? image.url : `/api/image/view/${image.url}`;
            }

            // 默认占位图
            return '';
        }

        // 处理图片加载错误
        function handleImageError(imgElement, imageId) {
            // 隐藏加载动画
            const spinner = imgElement.parentElement.querySelector('.loading-spinner');
            if (spinner) spinner.style.display = 'none';

            // 尝试备用URL
            const originalSrc = imgElement.src;

            // 如果不是API URL，尝试API URL
            if (!originalSrc.includes('/api/image/view/')) {
                const apiUrl = `/api/image/view/${imageId}`;
                if (originalSrc !== apiUrl) {
                    imgElement.src = apiUrl;
                    return;
                }
            }

            // 如果API URL也失败，尝试添加时间戳避免缓存
            if (!originalSrc.includes('?t=')) {
                const timestampUrl = `${originalSrc}?t=${Date.now()}`;
                imgElement.src = timestampUrl;
                return;
            }

            // 最终使用占位图
            imgElement.src = '';
            imgElement.style.opacity = '0.5';
            imgElement.title = '图片加载失败';
        }

        // 显示空图片库
        function showEmptyGallery() {
            const container = document.getElementById('imageGalleryContainer');
            if (container) {
                container.innerHTML = `
                    <div class="text-center text-muted py-5">
                        <i class="fas fa-images fa-4x mb-3" style="opacity: 0.3;"></i>
                        <h5>图片库中暂无图片</h5>
                        <p>您可以先上传一些图片到图片库</p>
                        <a href="/image-gallery" class="btn btn-outline-primary" target="_blank">
                            <i class="fas fa-upload"></i> 前往图片库上传
                        </a>
                    </div>
                `;
            }

            // 清空分页
            const paginationList = document.getElementById('paginationList');
            if (paginationList) paginationList.innerHTML = '';

            const statsElement = document.getElementById('imageStats');
            if (statsElement) statsElement.textContent = '共 0 张图片';
        }

        // 显示图片库错误
        function showGalleryError(errorMessage) {
            const container = document.getElementById('imageGalleryContainer');
            if (container) {
                container.innerHTML = `
                    <div class="text-center text-danger py-5">
                        <i class="fas fa-exclamation-triangle fa-3x mb-3"></i>
                        <h5>加载图片库失败</h5>
                        <p>${escapeHtml(errorMessage)}</p>
                        <button class="btn btn-outline-danger" onclick="initImageGallery()">
                            <i class="fas fa-redo"></i> 重新加载
                        </button>
                    </div>
                `;
            }
        }

        // 获取分类名称
        function getCategoryName(category) {
            const categoryNames = {
                'ai_generated': 'AI生成',
                'web_search': '网络搜索',
                'network_search': '网络搜索',
                'network': '网络搜索',
                'local_storage': '本地上传',
                'local_upload': '本地上传',
                'local': '本地上传'
            };
            return categoryNames[category] || category;
        }

        // 获取图片分类标签
        function getImageCategoryBadge(image) {
            let category = '';
            let badgeClass = 'bg-secondary';

            // 尝试从多个字段确定分类
            if (image.category) {
                category = image.category;
            } else if (image.source) {
                category = image.source;
            } else if (image.source_type) {
                category = image.source_type;
            } else if (image.generation_prompt) {
                category = 'ai_generated';
            } else if (image.url && image.url.includes('/network/')) {
                category = 'web_search';
            } else if (image.url && image.url.includes('/local/')) {
                category = 'local_storage';
            }

            // 设置对应的样式 - 修复分类映射
            switch (category) {
                case 'ai_generated':
                    badgeClass = 'bg-success';
                    break;
                case 'web_search':
                case 'network_search':
                case 'network':
                    badgeClass = 'bg-info';
                    break;
                case 'local_storage':
                case 'local_upload':
                case 'local':
                    badgeClass = 'bg-primary';
                    break;
            }

            if (category) {
                return `<small class="d-block"><span class="badge ${badgeClass}">${getCategoryName(category)}</span></small>`;
            }

            return '';
        }

        // HTML转义函数
        function escapeHtml(text) {
            const div = document.createElement('div');
            div.textContent = text;
            return div.innerHTML;
        }

        // 辅助函数：转义正则表达式特殊字符
        function escapeRegExp(string) {
            return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
        }

        // 通知AI助手图像已选择
        function notifyAIAssistantImageSelected(imageInfo) {
            // 更新AI助手界面显示选中的图像信息
            updateAIAssistantSelectedImage(imageInfo);

            // 如果AI助手侧栏未打开，则打开它
            const sidebar = document.getElementById('aiEditSidebar');
            if (!sidebar.classList.contains('open')) {
                openAIEditSidebar();
            }
        }

        // 响应式缩放辅助函数
        function getResponsiveScale() {
            const width = window.innerWidth;
            if (width <= 576) return 'scale(0.06)';
            if (width <= 768) return 'scale(0.08)';
            if (width <= 992) return 'scale(0.1)';
            if (width <= 1200) return 'scale(0.12)';
            return 'scale(0.15)';
        }

        function getResponsiveWidth() {
            const width = window.innerWidth;
            if (width <= 576) return '1667%';
            if (width <= 768) return '1250%';
            if (width <= 992) return '1000%';
            if (width <= 1200) return '833%';
            return '667%';
        }

        function getResponsiveHeight() {
            const width = window.innerWidth;
            if (width <= 576) return '1667%';
            if (width <= 768) return '1250%';
            if (width <= 992) return '1000%';
            if (width <= 1200) return '833%';
            return '667%';
        }

        // 窗口大小改变时重新应用缩放
        window.addEventListener('resize', function() {
            const iframes = document.querySelectorAll('.slide-preview iframe');
            iframes.forEach(iframe => {
                iframe.style.transform = getResponsiveScale();
                iframe.style.width = getResponsiveWidth();
                iframe.style.height = getResponsiveHeight();
            });
        });

        // 点击其他地方隐藏右键菜单
        document.addEventListener('click', function(event) {
            if (!event.target.closest('.context-menu')) {
                hideContextMenu();
            }
        });

        // 阻止页面默认右键菜单
        document.addEventListener('contextmenu', function(event) {
            if (!event.target.closest('.slide-thumbnail')) {
                // 只在非幻灯片区域阻止默认右键菜单
                // event.preventDefault();
            }
        });



        // 移除重复的checkForUpdates函数定义 - 已在上面定义

        // 更新主预览区域
        function updateMainPreviewArea() {
            const previewPane = document.getElementById('previewPane');
            if (!previewPane) return;

            if (hasSlidesData && slidesData.length > 0) {
                // 如果有幻灯片数据，更新预览区域
                previewPane.innerHTML = `
                    <div class="slide-frame-container">
                        <div class="slide-frame-wrapper" id="slideFrameWrapper">
                            <iframe class="slide-frame" id="slideFrame"
                                    title="Slide Preview"></iframe>
                            <div class="quick-edit-overlay" id="quickEditOverlay"></div>
                        </div>
                    </div>
                `;

                // 设置第一张幻灯片的内容
                const slideFrame = document.getElementById('slideFrame');
                if (slideFrame && slidesData[0]) {
                    setSafeIframeContent(slideFrame, slidesData[0].html_content);

                    // 初始化iframe和重新初始化JavaScript
                    setTimeout(() => {
                        initializeMainFrame();
                        applyMainFrameScale();
                        forceReinitializeIframeJS(slideFrame);
                    }, 100);
                }
            } else {
                // 如果没有幻灯片数据，显示等待界面
                previewPane.innerHTML = `
                    <div class="d-flex align-items-center justify-content-center h-100" style="background: #f8f9fa; border-radius: 8px;">
                        <div class="text-center" style="color: #6c757d;">
                            <div style="font-size: 64px; margin-bottom: 20px;">
                                <i class="fas fa-presentation-screen"></i>
                            </div>
                            <h4 style="margin-bottom: 15px;">等待PPT生成</h4>
                            <p style="margin-bottom: 20px;">PPT生成完成后，预览将在这里显示</p>
                            <button class="btn btn-outline-primary" onclick="checkForUpdates()">
                                <i class="fas fa-refresh"></i> 刷新页面
                            </button>
                        </div>
                    </div>
                `;
            }
        }

        // 页面加载完成后应用响应式缩放和绑定事件
        document.addEventListener('DOMContentLoaded', function() {
            // 为所有现有的iframe应用响应式缩放
            const iframes = document.querySelectorAll('.slide-preview iframe');
            iframes.forEach(iframe => {
                iframe.style.transform = getResponsiveScale();
                iframe.style.width = getResponsiveWidth();
                iframe.style.height = getResponsiveHeight();
            });

            // 初始化右侧主iframe
            setTimeout(() => {
                initializeMainFrame();
                applyMainFrameScale();
            }, 100);

            // 初始化缩略图事件监听器
            initializeThumbnailEvents();

            // 初始化AI侧栏宽度调整功能
            initializeSidebarResize();

            // 初始化CodeMirror编辑器
            initializeCodeMirror();

            // 初始化代码编辑器自动保存（fallback）
            initializeCodeEditorAutoSave();

            // 绑定按钮事件监听器
            const slideshowBtn = document.getElementById('slideshowBtn');
            const saveSlideBtn = document.getElementById('saveSlideBtn');
            const aiEditBtn = document.getElementById('aiEditBtn');

            if (slideshowBtn) {
                slideshowBtn.addEventListener('click', startSlideshow);
            }
            if (saveSlideBtn) {
                saveSlideBtn.addEventListener('click', saveSlide);
            }
            if (aiEditBtn) {
                aiEditBtn.addEventListener('click', openAIEditSidebar);
            }

            // 绑定AI输入框回车键事件
            const aiInputBox = document.getElementById('aiInputBox');
            if (aiInputBox) {
                aiInputBox.addEventListener('keydown', function(event) {
                    if (event.key === 'Enter' && !event.shiftKey) {
                        event.preventDefault();
                        sendAIMessage();
                    }
                });
            }

            // 确保第一张幻灯片被选中
            if (hasSlidesData && slidesData.length > 0) {
                selectSlide(0);
            }

            // 更新功能按钮状态
            updateFunctionButtonsState();

            // 移除自动检查逻辑，只在页面加载时检查一次
            // setTimeout(checkForUpdates, 1000); - 已移除
            // setTimeout(startAutoCheck, 2000); - 已移除
        });

        // 防抖函数，优化窗口大小变化时的性能
        let resizeTimeout;
        function debounceResize() {
            clearTimeout(resizeTimeout);
            resizeTimeout = setTimeout(() => {
                // 重新计算左侧缩略图缩放
                const iframes = document.querySelectorAll('.slide-preview iframe');
                iframes.forEach(iframe => {
                    iframe.style.transform = getResponsiveScale();
                    iframe.style.width = getResponsiveWidth();
                    iframe.style.height = getResponsiveHeight();
                });

                // 清除缓存的缩放比例，强制重新计算
                cachedScale = null;
                lastContainerSize = null;

                // 重新计算主iframe缩放
                applyMainFrameScale();

                // 重新计算CodeMirror编辑器尺寸
                resizeCodeMirror();
            }, 150); // 防抖延迟150ms
        }

        // 窗口大小改变时使用防抖处理
        window.addEventListener('resize', debounceResize);

        // 触摸手势支持，提升移动设备体验
        let touchStartX = 0;
        let touchStartY = 0;
        let touchEndX = 0;
        let touchEndY = 0;
        let touchStartTime = 0;

        function initializeSlideshowTouchGestures() {
            const overlay = document.getElementById('slideshowOverlay');

            overlay.addEventListener('touchstart', handleTouchStart, { passive: true });
            overlay.addEventListener('touchend', handleTouchEnd, { passive: true });
            overlay.addEventListener('touchmove', handleTouchMove, { passive: false });
        }

        function removeSlideshowTouchGestures() {
            const overlay = document.getElementById('slideshowOverlay');

            overlay.removeEventListener('touchstart', handleTouchStart);
            overlay.removeEventListener('touchend', handleTouchEnd);
            overlay.removeEventListener('touchmove', handleTouchMove);
        }

        function handleTouchStart(e) {
            if (!isSlideshow || e.touches.length !== 1) return;

            const touch = e.touches[0];
            touchStartX = touch.clientX;
            touchStartY = touch.clientY;
            touchStartTime = Date.now();
        }

        function handleTouchMove(e) {
            if (!isSlideshow || e.touches.length !== 1) return;

            // 防止页面滚动
            e.preventDefault();
        }

        function handleTouchEnd(e) {
            if (!isSlideshow || e.changedTouches.length !== 1) return;

            const touch = e.changedTouches[0];
            touchEndX = touch.clientX;
            touchEndY = touch.clientY;

            const deltaX = touchEndX - touchStartX;
            const deltaY = touchEndY - touchStartY;
            const deltaTime = Date.now() - touchStartTime;

            // 检查是否为有效的滑动手势
            const minSwipeDistance = 50;
            const maxSwipeTime = 500;
            const maxVerticalDistance = 100;

            if (deltaTime > maxSwipeTime) return;
            if (Math.abs(deltaY) > maxVerticalDistance) return;

            if (Math.abs(deltaX) > minSwipeDistance) {
                if (deltaX > 0) {
                    // 向右滑动 - 上一张
                    previousSlideshow();
                } else {
                    // 向左滑动 - 下一张
                    nextSlideshow();
                }
            } else if (Math.abs(deltaX) < 10 && Math.abs(deltaY) < 10) {
                // 点击手势 - 下一张
                nextSlideshow();
            }
        }
    </script>

    <!-- CodeMirror JavaScript -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/codemirror.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/xml/xml.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/javascript/javascript.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/css/css.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/mode/htmlmixed/htmlmixed.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/edit/closetag.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/edit/closebrackets.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/edit/matchtags.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/fold/foldcode.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/fold/foldgutter.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/fold/xml-fold.min.js"></script>
    <!-- CodeMirror Search功能 -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/dialog/dialog.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/search/searchcursor.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.2/addon/search/search.min.js"></script>

    <script>
        // 图片上传相关函数
        function triggerImageUpload() {
            if (isUploading) {
                showNotification('正在上传中，请稍候...', 'warning');
                return;
            }
            showImageSelectMenu();
        }

        // 初始化图片上传功能
        function initImageUpload() {
            const fileInput = document.getElementById('aiImageFileInput');
            const uploadBtn = document.getElementById('aiImageUploadBtn');
            const inputContainer = document.querySelector('.ai-input-container');

            console.log('初始化图片上传功能，元素检查:', {
                fileInput: !!fileInput,
                uploadBtn: !!uploadBtn,
                inputContainer: !!inputContainer
            });

            if (!fileInput || !uploadBtn || !inputContainer) {
                console.error('图片上传初始化失败：缺少必要元素');
                return;
            }

            // 文件选择处理
            fileInput.addEventListener('change', handleFileSelect);
            console.log('文件选择事件已绑定');

            // 拖拽事件处理 - 使用重命名的函数避免冲突
            inputContainer.addEventListener('dragenter', handleImageDragEnter);
            inputContainer.addEventListener('dragover', handleImageDragOver);
            inputContainer.addEventListener('dragleave', handleImageDragLeave);
            inputContainer.addEventListener('drop', handleImageFileDrop);

            console.log('拖拽事件已绑定到输入容器');

            // 阻止默认拖拽行为
            ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
                inputContainer.addEventListener(eventName, preventImageDefaults, false);
            });

            console.log('图片上传功能初始化完成');
        }

        // 检查是否为文件拖拽
        function isFileDrag(e) {
            return e.dataTransfer &&
                   e.dataTransfer.types &&
                   (e.dataTransfer.types.includes('Files') ||
                    e.dataTransfer.types.includes('application/x-moz-file'));
        }

        function preventImageDefaults(e) {
            // 只处理文件拖拽，不影响其他拖拽操作
            if (isFileDrag(e)) {
                e.preventDefault();
                e.stopPropagation();
                console.log('阻止默认行为:', e.type);
            }
        }

        function handleImageDragEnter(e) {
            console.log('dragenter事件触发', e.dataTransfer?.types);
            if (isFileDrag(e)) {
                e.preventDefault();
                const inputContainer = document.querySelector('.ai-input-container');
                inputContainer.classList.add('drag-over');
                console.log('拖拽进入输入区域');
            }
        }

        function handleImageDragOver(e) {
            if (isFileDrag(e)) {
                e.preventDefault();
                e.dataTransfer.dropEffect = 'copy';
                console.log('拖拽悬停在输入区域');
            }
        }

        function handleImageDragLeave(e) {
            console.log('dragleave事件触发');
            if (isFileDrag(e)) {
                // 检查是否真的离开了容器区域
                const inputContainer = document.querySelector('.ai-input-container');
                const rect = inputContainer.getBoundingClientRect();
                const x = e.clientX;
                const y = e.clientY;

                if (x < rect.left || x > rect.right || y < rect.top || y > rect.bottom) {
                    inputContainer.classList.remove('drag-over');
                    console.log('拖拽离开输入区域');
                }
            }
        }

        function handleImageFileDrop(e) {
            console.log('drop事件触发', e.dataTransfer);

            // 总是阻止默认行为
            e.preventDefault();
            e.stopPropagation();

            const inputContainer = document.querySelector('.ai-input-container');
            inputContainer.classList.remove('drag-over');

            if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length > 0) {
                const files = e.dataTransfer.files;
                console.log('检测到拖拽文件:', files.length, '个文件');

                // 过滤出图片文件
                const imageFiles = Array.from(files).filter(file => file.type.startsWith('image/'));

                if (imageFiles.length > 0) {
                    console.log('处理图片文件:', imageFiles.length, '个图片');
                    handleFiles(imageFiles);
                    showNotification(`检测到 ${imageFiles.length} 张图片，正在上传...`, 'info');
                } else {
                    showNotification('请拖拽图片文件到此区域', 'warning');
                }
            } else {
                console.log('未检测到文件或拖拽数据为空');
                showNotification('拖拽失败，请重试', 'error');
            }
        }

        function handleFileSelect(e) {
            const files = e.target.files;
            handleFiles(files);
        }

        function handleFiles(files) {
            if (isUploading) {
                showNotification('正在上传中，请稍候...', 'warning');
                return;
            }

            // 支持的图片格式
            const supportedTypes = [
                'image/jpeg', 'image/jpg', 'image/png', 'image/gif',
                'image/webp', 'image/bmp', 'image/svg+xml'
            ];

            const validFiles = [];
            const errors = [];

            Array.from(files).forEach(file => {
                // 验证文件类型
                if (!supportedTypes.includes(file.type.toLowerCase())) {
                    errors.push(`${file.name}: 不支持的图片格式 (${file.type})`);
                    return;
                }

                // 验证文件大小 (10MB)
                if (file.size > 10 * 1024 * 1024) {
                    errors.push(`${file.name}: 文件大小超过10MB限制 (${formatFileSize(file.size)})`);
                    return;
                }

                // 验证文件名
                if (file.name.length > 100) {
                    errors.push(`${file.name}: 文件名过长，请使用较短的文件名`);
                    return;
                }

                validFiles.push(file);
            });

            // 显示错误信息
            if (errors.length > 0) {
                const errorMessage = '以下文件无法上传：\n' + errors.join('\n');
                showNotification(errorMessage, 'error');
            }

            if (validFiles.length === 0) {
                if (errors.length === 0) {
                    showNotification('没有选择有效的图片文件', 'warning');
                }
                return;
            }

            // 检查是否超过最大上传数量
            const maxImages = 10;
            if (uploadedImages.length + validFiles.length > maxImages) {
                showNotification(`最多只能上传${maxImages}张图片，当前已有${uploadedImages.length}张`, 'warning');
                return;
            }

            // 上传文件
            uploadFiles(validFiles);
        }

        async function uploadFiles(files) {
            if (files.length === 0) return;

            isUploading = true;
            showUploadProgress(true);

            try {
                for (let i = 0; i < files.length; i++) {
                    const file = files[i];
                    updateUploadProgress((i / files.length) * 100, `上传中 ${i + 1}/${files.length}: ${file.name}`);

                    const result = await uploadSingleFile(file);
                    if (result.success) {
                        addUploadedImage(result.data);
                    } else {
                        showNotification(`上传失败: ${file.name} - ${result.message}`, 'error');
                    }
                }

                updateUploadProgress(100, '上传完成');
                setTimeout(() => showUploadProgress(false), 1000);

                showNotification(`成功上传 ${files.length} 张图片`, 'success');

            } catch (error) {
                console.error('上传失败:', error);
                showNotification('上传失败，请重试', 'error');
            } finally {
                isUploading = false;
                setTimeout(() => showUploadProgress(false), 1000);
            }
        }

        async function uploadSingleFile(file) {
            const formData = new FormData();
            formData.append('file', file);
            formData.append('title', file.name.split('.')[0]);
            formData.append('description', `AI编辑助手上传的图片: ${file.name}`);
            formData.append('category', 'ai_assistant');
            formData.append('tags', 'ai_assistant,ppt_edit');

            try {
                const response = await fetch('/api/image/upload', {
                    method: 'POST',
                    body: formData
                });

                const result = await response.json();

                if (result.success) {
                    // 获取图片的绝对URL
                    const imageUrl = await getImageAbsoluteUrl(result.image_id);
                    return {
                        success: true,
                        data: {
                            id: result.image_id,
                            name: file.name,
                            size: file.size,
                            url: imageUrl,
                            file: file
                        }
                    };
                } else {
                    return {
                        success: false,
                        message: result.message || '上传失败'
                    };
                }
            } catch (error) {
                console.error('上传请求失败:', error);
                return {
                    success: false,
                    message: '网络错误'
                };
            }
        }

        async function getImageAbsoluteUrl(imageId) {
            try {
                const response = await fetch(`/api/image/${imageId}/info`);
                const result = await response.json();

                if (result.success && result.image_info) {
                    return result.image_info.absolute_url;
                } else {
                    // 如果获取失败，使用默认的URL格式
                    return `${window.location.origin}/api/image/${imageId}`;
                }
            } catch (error) {
                console.error('获取图片URL失败:', error);
                return `${window.location.origin}/api/image/${imageId}`;
            }
        }

        function showUploadProgress(show) {
            const progressDiv = document.getElementById('aiUploadProgress');
            progressDiv.style.display = show ? 'block' : 'none';

            if (!show) {
                updateUploadProgress(0, '');
            }
        }

        function updateUploadProgress(percent, text) {
            const progressFill = document.getElementById('aiProgressFill');
            const progressText = document.getElementById('aiProgressText');

            progressFill.style.width = `${percent}%`;
            progressText.textContent = text;
        }

        function addUploadedImage(imageData) {
            uploadedImages.push(imageData);
            renderUploadedImages();
        }

        function renderUploadedImages() {
            const container = document.getElementById('aiUploadedImages');
            const uploadBtn = document.getElementById('aiImageUploadBtn');

            container.innerHTML = '';

            // 更新上传按钮状态
            if (uploadedImages.length === 0) {
                uploadBtn.classList.remove('has-images');
                uploadBtn.removeAttribute('data-count');
                return;
            } else {
                uploadBtn.classList.add('has-images');
                uploadBtn.setAttribute('data-count', uploadedImages.length);
            }

            uploadedImages.forEach((image, index) => {
                const imageDiv = document.createElement('div');
                imageDiv.className = 'ai-uploaded-image';
                imageDiv.title = `${image.name} (${formatFileSize(image.size)}) - 点击查看大图`;

                // 创建图片预览
                const img = document.createElement('img');
                if (image.file) {
                    // 本地上传的图片
                    img.src = URL.createObjectURL(image.file);
                } else {
                    // 从图床选择的图片
                    img.src = image.url;
                }
                img.alt = image.name;

                // 创建删除按钮
                const removeBtn = document.createElement('button');
                removeBtn.className = 'ai-image-remove';
                removeBtn.innerHTML = '<i class="fas fa-times"></i>';
                removeBtn.onclick = (e) => {
                    e.stopPropagation();
                    removeUploadedImage(index);
                };

                // 创建信息显示
                const infoDiv = document.createElement('div');
                infoDiv.className = 'ai-image-info';
                infoDiv.textContent = formatFileSize(image.size);

                imageDiv.appendChild(img);
                imageDiv.appendChild(removeBtn);
                imageDiv.appendChild(infoDiv);

                // 点击图片显示全屏预览
                imageDiv.addEventListener('click', () => {
                    showImagePreview(image);
                });

                container.appendChild(imageDiv);
            });
        }

        function removeUploadedImage(index) {
            if (index >= 0 && index < uploadedImages.length) {
                const image = uploadedImages[index];
                // 释放blob URL（仅对本地上传的图片）
                if (image.file) {
                    URL.revokeObjectURL(URL.createObjectURL(image.file));
                }
                uploadedImages.splice(index, 1);
                renderUploadedImages();
                showNotification('图片已移除', 'info');
            }
        }



        function formatFileSize(bytes) {
            if (bytes === 0) return '0 B';
            const k = 1024;
            const sizes = ['B', 'KB', 'MB', 'GB'];
            const i = Math.floor(Math.log(bytes) / Math.log(k));
            return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
        }

        function clearUploadedImages() {
            // 释放所有blob URLs（仅对本地上传的图片）
            uploadedImages.forEach(image => {
                if (image.file) {
                    URL.revokeObjectURL(URL.createObjectURL(image.file));
                }
            });
            uploadedImages = [];
            renderUploadedImages();
        }



        // 自动将所有已上传的图片信息嵌入到消息中
        function autoEmbedUploadedImages(message) {
            if (uploadedImages.length === 0) {
                return message;
            }

            // 构建图片信息文本
            let imageInfoText = '\n\n📷 图片信息：\n';
            uploadedImages.forEach((image, index) => {
                imageInfoText += `${index + 1}. 图片名称：${image.name}\n`;
                imageInfoText += `   图片地址：${image.url}\n`;
                imageInfoText += `   文件大小：${formatFileSize(image.size)}\n`;
                if (index < uploadedImages.length - 1) {
                    imageInfoText += '\n';
                }
            });

            // imageInfoText += '\n请分析这些图片的内容，并根据我的要求进行处理。';

            return message + imageInfoText;
        }

        // 获取所有已上传的图片信息
        function getAllUploadedImages() {
            return uploadedImages.map(image => ({
                name: image.name,
                url: image.url,
                size: image.size > 0 ? formatFileSize(image.size) : '未知大小',
                id: image.id
            }));
        }



        // 全屏图片预览相关函数
        function showImagePreview(image) {
            currentPreviewImage = image;

            const overlay = document.getElementById('imagePreviewOverlay');
            const title = document.getElementById('imagePreviewTitle');
            const details = document.getElementById('imagePreviewDetails');
            const img = document.getElementById('imagePreviewImg');
            const loading = document.getElementById('imagePreviewLoading');

            // 显示遮罩层
            overlay.style.display = 'flex';

            // 设置图片信息
            title.textContent = image.name;
            details.textContent = `大小: ${formatFileSize(image.size)} | 发送消息时自动包含此图片`;

            // 显示加载状态
            loading.style.display = 'block';
            img.style.display = 'none';

            // 加载图片
            img.onload = function() {
                loading.style.display = 'none';
                img.style.display = 'block';
            };

            img.onerror = function() {
                loading.style.display = 'none';
                img.style.display = 'block';
                img.src = '';
            };

            // 设置图片源
            img.src = image.url;

            // 阻止页面滚动
            document.body.style.overflow = 'hidden';
        }

        function closeImagePreview() {
            const overlay = document.getElementById('imagePreviewOverlay');
            overlay.style.display = 'none';
            currentPreviewImage = null;

            // 恢复页面滚动
            document.body.style.overflow = '';
        }

        function downloadCurrentImage() {
            if (!currentPreviewImage) return;

            const link = document.createElement('a');
            link.href = currentPreviewImage.url;
            link.download = currentPreviewImage.name;
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);

            showNotification(`开始下载: ${currentPreviewImage.name}`, 'success');
        }



        function removeCurrentImage() {
            if (!currentPreviewImage) return;

            const index = uploadedImages.findIndex(img => img.id === currentPreviewImage.id);
            if (index !== -1) {
                if (confirm(`确定要删除图片 "${currentPreviewImage.name}" 吗？`)) {
                    removeUploadedImage(index);
                    closeImagePreview();
                }
            }
        }

        // 键盘事件处理
        document.addEventListener('keydown', function(e) {
            if (e.key === 'Escape' && currentPreviewImage) {
                closeImagePreview();
            }
        });

        // 点击遮罩层关闭预览
        document.addEventListener('click', function(e) {
            if (e.target.id === 'imagePreviewOverlay') {
                closeImagePreview();
            }
        });

        // 图片选择菜单相关函数
        function showImageSelectMenu() {
            const menu = document.getElementById('imageSelectMenu');
            menu.style.display = 'flex';
            document.body.style.overflow = 'hidden';
        }

        function closeImageSelectMenu() {
            const menu = document.getElementById('imageSelectMenu');
            menu.style.display = 'none';
            document.body.style.overflow = '';
        }

        function selectFromLocal() {
            closeImageSelectMenu();
            const fileInput = document.getElementById('aiImageFileInput');
            fileInput.click();
        }

        function selectFromLibrary() {
            closeImageSelectMenu();
            showImageLibrary();
        }

        // 图床选择器相关函数
        function showImageLibrary() {
            const overlay = document.getElementById('imageLibraryOverlay');
            const loading = document.getElementById('imageLibraryLoading');
            const grid = document.getElementById('imageLibraryGrid');
            const empty = document.getElementById('imageLibraryEmpty');

            overlay.style.display = 'flex';
            loading.style.display = 'block';
            grid.style.display = 'none';
            empty.style.display = 'none';

            selectedLibraryImages = [];
            updateSelectionCount();

            document.body.style.overflow = 'hidden';

            // 初始化搜索功能
            initImageLibrarySearch();

            // 加载图床图片
            loadLibraryImages();
        }

        function closeImageLibrary() {
            const overlay = document.getElementById('imageLibraryOverlay');
            overlay.style.display = 'none';
            selectedLibraryImages = [];
            document.body.style.overflow = '';

            // 重置搜索状态
            const searchInput = document.getElementById('imageLibrarySearchInput');
            const clearBtn = document.getElementById('imageLibrarySearchClear');
            if (searchInput) {
                searchInput.value = '';
            }
            if (clearBtn) {
                clearBtn.style.display = 'none';
            }
            currentSearchTerm = '';
            filteredLibraryImages = [];

            // 重置分页状态
            currentPage = 1;
            totalPages = 1;
            totalCount = 0;
            hidePaginationUI();
        }

        async function loadLibraryImages(searchTerm = '', page = 1) {
            try {
                // 使用与image_gallery.html相同的API端点
                const params = new URLSearchParams({
                    page: page,
                    per_page: perPage,
                    category: '', // 不限制分类
                    search: searchTerm,
                    sort: 'created_desc'
                });

                const response = await fetch(`/api/image/gallery/list?${params}`);
                const result = await response.json();

                const loading = document.getElementById('imageLibraryLoading');
                const grid = document.getElementById('imageLibraryGrid');
                const empty = document.getElementById('imageLibraryEmpty');

                loading.style.display = 'none';

                if (result.success && result.images && result.images.length > 0) {
                    libraryImages = result.images;
                    filteredLibraryImages = libraryImages;

                    // 更新分页信息
                    if (result.pagination) {
                        currentPage = result.pagination.current_page;
                        totalPages = result.pagination.total_pages;
                        totalCount = result.pagination.total_count;
                        updatePaginationUI();
                    }

                    console.log('加载到的图片数量:', libraryImages.length);
                    console.log('第一张图片的数据结构:', libraryImages[0]);
                    renderLibraryImages();
                    grid.style.display = 'grid';
                } else {
                    console.log('没有找到图片或API调用失败');
                    empty.style.display = 'block';
                    hidePaginationUI();
                }
            } catch (error) {
                console.error('加载图床图片失败:', error);
                const loading = document.getElementById('imageLibraryLoading');
                const empty = document.getElementById('imageLibraryEmpty');

                loading.style.display = 'none';
                empty.style.display = 'block';
                empty.innerHTML = `
                    <i class="fas fa-exclamation-triangle"></i>
                `;
                showNotification('加载图床图片失败', 'error');
            }
        }

        function renderLibraryImages() {
            const grid = document.getElementById('imageLibraryGrid');
            grid.innerHTML = '';

            filteredLibraryImages.forEach(image => {
                const item = document.createElement('div');
                item.className = 'image-library-item';
                item.dataset.imageId = image.image_id;

                // 构建图片URL
                const imageUrl = `/api/image/view/${image.image_id}`;

                // 格式化文件大小 - 检查多个可能的位置
                let fileSize = '未知大小';
                if (image.file_size && image.file_size > 0) {
                    // 直接从根级别获取file_size
                    fileSize = formatFileSize(image.file_size);
                } else if (image.metadata) {
                    // 从metadata中获取
                    if (image.metadata.file_size && image.metadata.file_size > 0) {
                        fileSize = formatFileSize(image.metadata.file_size);
                    } else if (image.metadata.size && image.metadata.size > 0) {
                        fileSize = formatFileSize(image.metadata.size);
                    }
                }

                item.innerHTML = `
                    <img src="${imageUrl}" alt="${image.title || '未命名图片'}" loading="lazy" onerror="this.src=''">
                    <div class="image-info">
                        <div>${image.title || '未命名图片'}</div>
                        <div>${fileSize}</div>
                    </div>
                    <div class="selection-indicator">
                        <i class="fas fa-check"></i>
                    </div>
                `;

                item.addEventListener('click', () => toggleImageSelection(image, item));
                grid.appendChild(item);
            });
        }

        function toggleImageSelection(image, element) {
            const imageId = image.image_id;
            const index = selectedLibraryImages.findIndex(img => img.image_id === imageId);

            if (index === -1) {
                // 添加到选择列表
                selectedLibraryImages.push(image);
                element.classList.add('selected');
            } else {
                // 从选择列表移除
                selectedLibraryImages.splice(index, 1);
                element.classList.remove('selected');
            }

            updateSelectionCount();
        }

        function updateSelectionCount() {
            const countSpan = document.getElementById('selectedCount');
            const confirmBtn = document.getElementById('confirmSelectionBtn');

            countSpan.textContent = selectedLibraryImages.length;
            confirmBtn.disabled = selectedLibraryImages.length === 0;
        }

        async function confirmImageSelection() {
            if (selectedLibraryImages.length === 0) return;

            let addedCount = 0;

            // 显示处理进度
            showNotification('正在处理选择的图片...', 'info');

            // 逐个处理选择的图片，获取完整信息
            for (const image of selectedLibraryImages) {
                try {
                    // 获取图片的完整信息和绝对URL
                    const imageInfo = await getImageCompleteInfo(image.image_id);

                    const imageData = {
                        id: image.image_id,
                        name: imageInfo.name || image.title || '未命名图片',
                        size: imageInfo.size || 0,
                        url: imageInfo.absoluteUrl,
                        file: null // 从图床选择的图片没有file对象
                    };

                    // 检查是否已经存在
                    const exists = uploadedImages.find(img => img.id === imageData.id);
                    if (!exists) {
                        uploadedImages.push(imageData);
                        addedCount++;
                    }
                } catch (error) {
                    console.error(`获取图片 ${image.image_id} 信息失败:`, error);
                    // 如果获取详细信息失败，使用基本信息
                    const imageData = {
                        id: image.image_id,
                        name: image.title || '未命名图片',
                        size: image.file_size || (image.metadata && image.metadata.file_size) || 0,
                        url: `${window.location.origin}/api/image/view/${image.image_id}`,
                        file: null
                    };

                    const exists = uploadedImages.find(img => img.id === imageData.id);
                    if (!exists) {
                        uploadedImages.push(imageData);
                        addedCount++;
                    }
                }
            }

            renderUploadedImages();
            closeImageLibrary();

            if (addedCount > 0) {
                showNotification(`已添加 ${addedCount} 张图片`, 'success');
            } else {
                showNotification('所选图片已存在，未添加新图片', 'info');
            }
        }

        // 获取图片的完整信息，包括绝对URL
        async function getImageCompleteInfo(imageId) {
            try {
                const response = await fetch(`/api/image/${imageId}/info`);
                const result = await response.json();

                if (result.success && result.image_info) {
                    return {
                        name: result.image_info.title || result.image_info.filename,
                        size: result.image_info.file_size || 0,
                        absoluteUrl: result.image_info.absolute_url
                    };
                } else {
                    throw new Error('获取图片信息失败');
                }
            } catch (error) {
                console.error('获取图片完整信息失败:', error);
                // 如果专用接口失败，尝试使用详情接口
                try {
                    const detailResponse = await fetch(`/api/image/detail/${imageId}`);
                    const detailResult = await detailResponse.json();

                    if (detailResult.success && detailResult.image) {
                        const image = detailResult.image;
                        return {
                            name: image.title || image.filename,
                            size: (image.metadata && image.metadata.file_size) ? image.metadata.file_size : 0,
                            absoluteUrl: `${window.location.origin}/api/image/view/${imageId}`
                        };
                    }
                } catch (detailError) {
                    console.error('获取图片详情也失败:', detailError);
                }

                throw error;
            }
        }

        // 分页相关函数
        function updatePaginationUI() {
            const pagination = document.getElementById('imageLibraryPagination');
            const paginationInfo = document.getElementById('paginationInfo');
            const prevBtn = document.getElementById('prevPageBtn');
            const nextBtn = document.getElementById('nextPageBtn');

            if (!pagination) return;

            // 显示分页控件
            pagination.style.display = 'flex';

            // 更新分页信息
            paginationInfo.textContent = `第 ${currentPage} 页，共 ${totalPages} 页 (总计 ${totalCount} 张图片)`;

            // 更新按钮状态
            prevBtn.disabled = currentPage <= 1;
            nextBtn.disabled = currentPage >= totalPages;
        }

        function hidePaginationUI() {
            const pagination = document.getElementById('imageLibraryPagination');
            if (pagination) {
                pagination.style.display = 'none';
            }
        }

        function loadPreviousPage() {
            if (currentPage > 1) {
                loadLibraryImages(currentSearchTerm, currentPage - 1);
            }
        }

        function loadNextPage() {
            if (currentPage < totalPages) {
                loadLibraryImages(currentSearchTerm, currentPage + 1);
            }
        }

        // 图片库搜索相关函数
        function initImageLibrarySearch() {
            const searchInput = document.getElementById('imageLibrarySearchInput');
            const clearBtn = document.getElementById('imageLibrarySearchClear');

            if (!searchInput) return;

            // 搜索输入事件
            searchInput.addEventListener('input', function(e) {
                const searchTerm = e.target.value.trim();
                currentSearchTerm = searchTerm;

                if (searchTerm) {
                    clearBtn.style.display = 'block';
                    // 搜索时重置到第一页
                    loadLibraryImages(searchTerm, 1);
                } else {
                    clearBtn.style.display = 'none';
                    // 清空搜索时重置到第一页
                    loadLibraryImages('', 1);
                }
            });

            // 回车键搜索
            searchInput.addEventListener('keydown', function(e) {
                if (e.key === 'Enter') {
                    e.preventDefault();
                    const searchTerm = e.target.value.trim();
                    currentSearchTerm = searchTerm;
                    loadLibraryImages(searchTerm, 1);
                }
            });
        }



        function clearImageLibrarySearch() {
            const searchInput = document.getElementById('imageLibrarySearchInput');
            const clearBtn = document.getElementById('imageLibrarySearchClear');

            searchInput.value = '';
            clearBtn.style.display = 'none';
            currentSearchTerm = '';

            // 重新加载第一页数据
            loadLibraryImages('', 1);
        }

        // AI增强所有要点功能
        async function enhanceAllBulletPoints() {
            const bulletPointsContainer = document.getElementById('bulletPointsContainer');
            if (!bulletPointsContainer) {
                showNotification('找不到要点容器', 'error');
                return;
            }

            const bulletPointItems = bulletPointsContainer.querySelectorAll('.bullet-point-item');
            if (bulletPointItems.length === 0) {
                showNotification('没有要点可以增强', 'warning');
                return;
            }

            // 收集所有要点的原始内容
            const originalPoints = [];
            bulletPointItems.forEach((item, index) => {
                const textElement = item.querySelector('.bullet-point-text');
                const text = textElement ? textElement.textContent.trim() : '';
                if (text) {
                    originalPoints.push({
                        index: index,
                        text: text,
                        element: textElement
                    });
                }
            });

            if (originalPoints.length === 0) {
                showNotification('没有有效的要点内容可以增强', 'warning');
                return;
            }

            // 显示加载状态
            const enhanceAllBtn = event.target;
            const originalBtnContent = enhanceAllBtn.innerHTML;
            enhanceAllBtn.disabled = true;
            enhanceAllBtn.style.opacity = '0.6';
            enhanceAllBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> <span>正在增强...</span>';

            try {
                // 获取当前幻灯片和项目信息
                const currentSlide = slidesData[currentSlideIndex];
                let slideOutline = null;
                if (projectOutline && projectOutline.slides && projectOutline.slides[currentSlideIndex]) {
                    slideOutline = projectOutline.slides[currentSlideIndex];
                }

                // 构建AI增强请求
                const enhanceRequest = {
                    slideIndex: currentSlideIndex + 1,
                    slideTitle: currentSlide.title || `第${currentSlideIndex + 1}页`,
                    slideContent: currentSlide.html_content,
                    userRequest: `请增强和优化以下所有要点，使它们更加详细、准确和有吸引力。保持每个要点的核心意思不变，但可以添加更多细节、使用更好的表达方式或提供更具体的描述。要点之间应该保持逻辑连贯性和风格一致性。`,
                    slideOutline: slideOutline,
                    projectInfo: {
                        title: '{{ project.title }}',
                        topic: '{{ project.topic }}',
                        scenario: '{{ project.scenario }}'
                    },
                    contextInfo: {
                        allBulletPoints: originalPoints.map(p => p.text),
                        totalPoints: originalPoints.length
                    }
                };

                // 发送AI增强请求
                const response = await fetch('/api/ai/enhance-all-bullet-points', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(enhanceRequest)
                });

                if (!response.ok) {
                    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
                }

                const result = await response.json();

                if (result.success && result.enhancedPoints && Array.isArray(result.enhancedPoints)) {
                    // 显示增强结果的确认对话框
                    showAllBulletPointsEnhancementDialog(originalPoints, result.enhancedPoints);
                } else {
                    throw new Error(result.error || result.message || '增强失败');
                }

            } catch (error) {
                console.error('AI增强所有要点失败:', error);
                showNotification('AI增强失败：' + error.message, 'error');
            } finally {
                // 恢复按钮状态
                enhanceAllBtn.disabled = false;
                enhanceAllBtn.style.opacity = '1';
                enhanceAllBtn.innerHTML = originalBtnContent;
            }
        }

        // 键盘事件处理
        document.addEventListener('keydown', function(e) {
            if (e.key === 'Escape') {
                if (document.getElementById('bulletPointEnhancementDialog')) {
                    closeBulletPointEnhancementDialog();
                } else if (document.getElementById('imageSelectMenu').style.display === 'flex') {
                    closeImageSelectMenu();
                } else if (document.getElementById('imageLibraryOverlay').style.display === 'flex') {
                    closeImageLibrary();
                } else if (currentPreviewImage) {
                    closeImagePreview();
                }
            }
        });

        // 显示所有要点增强结果对话框
        function showAllBulletPointsEnhancementDialog(originalPoints, enhancedPoints) {
            // 创建对话框
            const dialog = document.createElement('div');
            dialog.id = 'bulletPointEnhancementDialog';
            dialog.style.cssText = `
                position: fixed;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background: rgba(0,0,0,0.6);
                z-index: 10002;
                display: flex;
                justify-content: center;
                align-items: center;
                backdrop-filter: blur(5px);
            `;

            const dialogContent = document.createElement('div');
            dialogContent.style.cssText = `
                background: white;
                border-radius: 12px;
                padding: 30px;
                width: 95vw;
                max-width: 1000px;
                max-height: 85vh;
                overflow-y: auto;
                position: relative;
                box-shadow: 0 20px 40px rgba(0,0,0,0.3);
                animation: slideInUp 0.3s ease;
            `;

            // 构建对比内容
            let comparisonContent = '';
            const maxLength = Math.max(originalPoints.length, enhancedPoints.length);

            for (let i = 0; i < maxLength; i++) {
                const original = originalPoints[i] ? originalPoints[i].text : '';
                const enhanced = enhancedPoints[i] ? cleanAIContent(enhancedPoints[i]) : '';

                if (original || enhanced) {
                    comparisonContent += `
                        <div style="margin-bottom: 25px; border: 1px solid #e9ecef; border-radius: 8px; overflow: hidden;">
                            <div style="background: #f8f9fa; padding: 10px 15px; border-bottom: 1px solid #e9ecef; font-weight: bold; color: #495057;">
                                要点 ${i + 1}
                            </div>
                            <div style="padding: 15px;">
                                <div style="margin-bottom: 15px;">
                                    <label style="font-weight: bold; display: block; margin-bottom: 8px; color: #dc3545; font-size: 13px;">原始内容：</label>
                                    <div style="background: #fff5f5; padding: 12px; border-radius: 6px; border-left: 3px solid #dc3545; font-size: 14px; line-height: 1.4; min-height: 20px;">
                                        ${original || '<em style="color: #999;">无内容</em>'}
                                    </div>
                                </div>
                                <div>
                                    <label style="font-weight: bold; display: block; margin-bottom: 8px; color: #28a745; font-size: 13px;">AI增强后：</label>
                                    <div style="background: #f0fff4; padding: 12px; border-radius: 6px; border-left: 3px solid #28a745; font-size: 14px; line-height: 1.4; min-height: 20px;">
                                        ${enhanced || '<em style="color: #999;">无增强内容</em>'}
                                    </div>
                                </div>
                            </div>
                        </div>
                    `;
                }
            }

            dialogContent.innerHTML = `
                <style>
                    @keyframes slideInUp {
                        from {
                            opacity: 0;
                            transform: translateY(30px);
                        }
                        to {
                            opacity: 1;
                            transform: translateY(0);
                        }
                    }
                </style>
                <h4 style="margin: 0 0 25px 0; color: #2c3e50; display: flex; align-items: center; gap: 10px;">
                    <span style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 50%; width: 32px; height: 32px; display: flex; align-items: center; justify-content: center; font-size: 16px;">🪄</span>
                    AI要点增强结果 (共 ${maxLength} 个要点)
                </h4>

                <div style="margin-bottom: 30px;">
                    ${comparisonContent}
                </div>

                <div style="text-align: right; display: flex; gap: 15px; justify-content: flex-end; border-top: 1px solid #e9ecef; padding-top: 20px;">
                    <button onclick="closeBulletPointEnhancementDialog()"
                            style="background: #6c757d; color: white; border: none; padding: 12px 24px; border-radius: 8px; cursor: pointer; font-size: 14px; font-weight: 500; transition: all 0.3s ease;">
                        <i class="fas fa-times"></i> 取消
                    </button>
                    <button onclick="applyAllBulletPointsEnhancement()"
                            style="background: linear-gradient(135deg, #28a745 0%, #20c997 100%); color: white; border: none; padding: 12px 24px; border-radius: 8px; cursor: pointer; font-size: 14px; font-weight: 500; transition: all 0.3s ease; box-shadow: 0 4px 15px rgba(40, 167, 69, 0.3);">
                        <i class="fas fa-check"></i> 应用所有增强
                    </button>
                </div>
            `;

            dialog.appendChild(dialogContent);
            document.body.appendChild(dialog);

            // 存储增强结果供后续使用
            dialog._enhancedPoints = enhancedPoints;
            dialog._originalPoints = originalPoints;

            // 点击遮罩关闭
            dialog.addEventListener('click', (e) => {
                if (e.target === dialog) {
                    closeBulletPointEnhancementDialog();
                }
            });
        }

        // 关闭要点增强对话框
        function closeBulletPointEnhancementDialog() {
            const dialog = document.getElementById('bulletPointEnhancementDialog');
            if (dialog) {
                document.body.removeChild(dialog);
            }
        }

        // 清理AI返回的内容，移除无关的开场白和格式标记
        function cleanAIContent(content) {
            if (!content) return '';

            // 移除常见的开场白模式
            const unwantedPatterns = [
                /^好的[，,。.]*.*?[。.]/,
                /^作为.*?专家[，,。.]*.*?[。.]/,
                /^我将.*?[。.]/,
                /^我会.*?[。.]/,
                /^以下是.*?[：:]/,
                /^根据.*?[：:]/,
                /^请注意.*?[：:]/,
                /^需要说明.*?[：:]/,
                /^增强后的要点.*?[：:]/,
                /^优化后的.*?[：:]/,
                /^改进后的.*?[：:]/
            ];

            let cleaned = content.trim();

            // 应用清理模式
            unwantedPatterns.forEach(pattern => {
                cleaned = cleaned.replace(pattern, '');
            });

            // 移除开头的编号和符号
            cleaned = cleaned.replace(/^[\d\s\.\-\*\•\·\→\▪\▫]+/, '').trim();

            return cleaned;
        }

        // 应用所有要点增强
        function applyAllBulletPointsEnhancement() {
            const dialog = document.getElementById('bulletPointEnhancementDialog');
            if (!dialog || !dialog._enhancedPoints || !dialog._originalPoints) {
                showNotification('无法获取增强结果', 'error');
                return;
            }

            const enhancedPoints = dialog._enhancedPoints;
            const originalPoints = dialog._originalPoints;
            const bulletPointsContainer = document.getElementById('bulletPointsContainer');

            if (!bulletPointsContainer) {
                showNotification('找不到要点容器', 'error');
                return;
            }

            let appliedCount = 0;

            // 更新现有要点，并清理内容
            originalPoints.forEach((originalPoint, index) => {
                if (enhancedPoints[index] && originalPoint.element) {
                    const cleanedContent = cleanAIContent(enhancedPoints[index]);
                    if (cleanedContent && cleanedContent.length >= 5) {
                        originalPoint.element.textContent = cleanedContent;
                        appliedCount++;
                    }
                }
            });

            // 如果增强后的要点比原始要点多，添加新要点
            if (enhancedPoints.length > originalPoints.length) {
                for (let i = originalPoints.length; i < enhancedPoints.length; i++) {
                    if (enhancedPoints[i]) {
                        const cleanedContent = cleanAIContent(enhancedPoints[i]);
                        if (cleanedContent && cleanedContent.length >= 5) {
                            addNewBulletPointWithContent(cleanedContent);
                            appliedCount++;
                        }
                    }
                }
            }

            closeBulletPointEnhancementDialog();

            if (appliedCount > 0) {
                showNotification(`已成功增强 ${appliedCount} 个要点！`, 'success');
            } else {
                showNotification('没有要点被增强', 'warning');
            }
        }

        // 添加带内容的新要点（用于增强功能）
        function addNewBulletPointWithContent(content) {
            const container = document.getElementById('bulletPointsContainer');
            if (!container) return;

            // 移除空状态提示
            const emptyState = container.querySelector('.empty-bullet-points');
            if (emptyState) {
                emptyState.remove();
            }

            // 获取当前要点数量
            const existingPoints = container.querySelectorAll('.bullet-point-item');
            const newIndex = existingPoints.length;

            // 创建新要点元素
            const newBulletPoint = document.createElement('div');
            newBulletPoint.className = 'bullet-point-item';
            newBulletPoint.setAttribute('data-index', newIndex);
            newBulletPoint.style.cssText = `
                display: flex;
                align-items: flex-start;
                margin-bottom: 8px;
                padding: 8px;
                border-radius: 4px;
                transition: all 0.2s ease;
                position: relative;
            `;

            newBulletPoint.innerHTML = `
                <span style="color: #666; margin-right: 8px; font-weight: bold; min-width: 20px;">•</span>
                <div style="flex: 1; position: relative;">
                    <div class="bullet-point-text" contenteditable="true"
                         style="outline: none; min-height: 20px; line-height: 1.4; word-wrap: break-word;">${content}</div>
                </div>
                <button class="delete-bullet-btn" onclick="deleteBulletPoint(${newIndex})"
                        style="background: #dc3545; color: white; border: none; border-radius: 50%; width: 28px; height: 28px; cursor: pointer; margin-left: 4px; display: flex; align-items: center; justify-content: center; font-size: 12px; transition: all 0.3s ease; opacity: 0.7;"
                        title="删除此要点">
                    <i class="fas fa-trash"></i>
                </button>
            `;

            container.appendChild(newBulletPoint);
        }

        // 点击遮罩层关闭
        document.addEventListener('click', function(e) {
            if (e.target.id === 'imageSelectMenu') {
                closeImageSelectMenu();
            } else if (e.target.id === 'imageLibraryOverlay') {
                closeImageLibrary();
            } else if (e.target.id === 'imagePreviewOverlay') {
                closeImagePreview();
            }
        });

        // 添加新要点功能
        function addNewBulletPoint() {
            const container = document.getElementById('bulletPointsContainer');
            if (!container) return;

            // 移除空状态提示
            const emptyState = container.querySelector('.empty-bullet-points');
            if (emptyState) {
                emptyState.remove();
            }

            // 获取当前要点数量
            const existingPoints = container.querySelectorAll('.bullet-point-item');
            const newIndex = existingPoints.length;

            // 创建新要点元素
            const newBulletPoint = document.createElement('div');
            newBulletPoint.className = 'bullet-point-item';
            newBulletPoint.setAttribute('data-index', newIndex);
            newBulletPoint.style.cssText = `
                display: flex;
                align-items: flex-start;
                margin-bottom: 8px;
                padding: 8px;
                border-radius: 4px;
                transition: all 0.2s ease;
                position: relative;
                background: rgba(40, 167, 69, 0.1);
                border: 2px dashed #28a745;
            `;

            newBulletPoint.innerHTML = `
                <span style="color: #666; margin-right: 8px; font-weight: bold; min-width: 20px;">•</span>
                <div style="flex: 1; position: relative;">
                    <div class="bullet-point-text" contenteditable="true"
                         style="outline: none; min-height: 20px; line-height: 1.4; word-wrap: break-word; background: white; padding: 8px; border-radius: 4px; border: 1px solid #28a745;"
                         placeholder="请输入新要点内容...">
                    </div>
                </div>

                <button class="delete-bullet-btn" onclick="deleteBulletPoint(${newIndex})"
                        style="background: #dc3545; color: white; border: none; border-radius: 50%; width: 28px; height: 28px; cursor: pointer; margin-left: 4px; display: flex; align-items: center; justify-content: center; font-size: 12px; transition: all 0.3s ease; opacity: 0.7;"
                        title="删除此要点">
                    <i class="fas fa-trash"></i>
                </button>
            `;

            container.appendChild(newBulletPoint);

            // 聚焦到新要点的文本区域
            const textArea = newBulletPoint.querySelector('.bullet-point-text');
            textArea.focus();

            // 添加事件监听器
            textArea.addEventListener('blur', function() {
                // 移除新建状态样式
                newBulletPoint.style.background = '';
                newBulletPoint.style.border = '';
                textArea.style.background = '';
                textArea.style.border = '';
                textArea.style.padding = '';
            });

            textArea.addEventListener('input', function() {
                if (this.textContent.trim()) {
                    // 有内容时移除新建状态样式
                    newBulletPoint.style.background = '';
                    newBulletPoint.style.border = '';
                    textArea.style.background = '';
                    textArea.style.border = '';
                    textArea.style.padding = '';
                }
            });

            showNotification('已添加新要点，请输入内容', 'info');
        }

        // 删除要点功能
        function deleteBulletPoint(pointIndex) {
            const bulletPointItem = document.querySelector(`.bullet-point-item[data-index="${pointIndex}"]`);
            if (!bulletPointItem) return;

            const pointText = bulletPointItem.querySelector('.bullet-point-text')?.textContent.trim();
            const confirmMessage = pointText ?
                `确定要删除要点"${pointText.substring(0, 30)}${pointText.length > 30 ? '...' : ''}"吗？` :
                '确定要删除这个要点吗？';

            if (confirm(confirmMessage)) {
                bulletPointItem.remove();

                // 重新编号剩余要点
                const container = document.getElementById('bulletPointsContainer');
                const remainingPoints = container.querySelectorAll('.bullet-point-item');

                remainingPoints.forEach((item, index) => {
                    item.setAttribute('data-index', index);
                    // 更新删除按钮的onclick事件
                    const deleteBtn = item.querySelector('.delete-bullet-btn');
                    if (deleteBtn) deleteBtn.setAttribute('onclick', `deleteBulletPoint(${index})`);
                });

                // 如果没有要点了，显示空状态
                if (remainingPoints.length === 0) {
                    container.innerHTML = `
                        <div class="empty-bullet-points" style="text-align: center; color: #999; padding: 40px 20px;">
                            <i class="fas fa-list" style="font-size: 24px; margin-bottom: 10px; opacity: 0.5;"></i>
                            <p style="margin: 0;">暂无要点，点击下方按钮添加</p>
                        </div>
                    `;
                }

                showNotification('要点已删除', 'info');
            }
        }

        // 验证和修复图片URL
        function validateAndFixImageUrls() {
            uploadedImages.forEach(image => {
                // 确保URL是绝对路径
                if (image.url && !image.url.startsWith('http') && !image.url.startsWith(window.location.origin)) {
                    if (image.url.startsWith('/')) {
                        image.url = window.location.origin + image.url;
                    } else {
                        image.url = window.location.origin + '/' + image.url;
                    }
                }

                // 确保文件大小是数字
                if (typeof image.size === 'string') {
                    image.size = parseInt(image.size) || 0;
                }
            });
        }

        // 添加键盘快捷键支持
        document.addEventListener('keydown', function(e) {
            // Ctrl/Cmd + E 切换快速编辑模式
            if ((e.ctrlKey || e.metaKey) && e.key === 'e' && !e.shiftKey && !e.altKey) {
                e.preventDefault();
                toggleQuickEditMode();
            }

            // ESC 键退出快速编辑模式
            if (e.key === 'Escape' && currentMode === 'quickedit') {
                if (currentInlineEditor) {
                    finishDirectEdit(false); // 取消编辑
                } else {
                    setMode('preview');
                }
            }
        });

        // 在页面加载完成后初始化图片上传功能
        document.addEventListener('DOMContentLoaded', function() {
            // 延迟初始化，确保所有元素都已加载
            setTimeout(() => {
                const imageUploadBtn = document.getElementById('aiImageUploadBtn');
                const inputContainer = document.querySelector('.ai-input-container');

                if (imageUploadBtn && inputContainer) {
                    console.log('初始化图片上传功能');
                    if (typeof initImageUpload === 'function') {
                        initImageUpload();
                    }

                    // 验证和修复现有图片数据
                    if (typeof validateAndFixImageUrls === 'function') {
                        validateAndFixImageUrls();
                    }
                } else {
                    console.log('图片上传元素未找到:', {
                        uploadBtn: !!imageUploadBtn,
                        inputContainer: !!inputContainer
                    });
                }
            }, 100);
        });
    </script>
</body>
</html>
